Compare commits

..

1 Commits

Author SHA1 Message Date
iliajie
fd3e985cf8 Fix to work-around the bug with time offsets #552 2023-04-25 23:04:58 +03:00
55766 changed files with 1903814 additions and 62163 deletions

9
.gitattributes vendored Normal file
View File

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

23
.gitignore vendored Normal file
View File

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

510
CHANGELOG.md Normal file
View File

@@ -0,0 +1,510 @@
## Changelog
#### 2.021 (March 19, 2023)
* Add ability to set locale in Webmin Users module for consistency
* Fix an error when `make_date` is called on undefined value #1860
* Fix clearing packages caches before checking for updates in status collection #1863
* Update the Authentic theme to the latest version
#### 2.020 (March 08, 2023)
* Add full locale support
* Add slave zone file format option in BIND DNS module
* Add support for editing ACLs in File Manager
* Add support to configure SSL connection for MySQL/MariaDB module
* Add support for compressed backups in PostgreSQL module
* Add support for displaying inodes too in Disk Usage in the Dashboard
* Add better support for CloudLinux
* Fix to always default to RSA key type in Let's Encrypt requests
* Fix setup repository script for Oracle
* Fix shutdown timeout to avoid termination of running processes
* Fix support for SpamAssassin 4
* Fix to use system default hashing format for `htpasswd` file
* Fix FastRPC issues
* Update the Authentic theme to the latest version, with sped-up Dashboard performance
#### 2.013 (January 19, 2023)
* Fix Authentic theme issue with error handling
* Fix Framed theme to respect selected mode in left menu
* Fix search bar in left menu in Framed theme
#### 2.012 (January 18, 2023)
* Fix to set the correct algorithm when setting up RNDC #1817
* Fix the loop bug when sourcing other network configs in Debian
* Fix to include all Debian network config files in backups
* Fix to stop doing expensive package re-fetch on upgrades
* Add support for defining hostname for WebSocket connection
* Add Debian 12 support
#### 2.011 (January 10, 2023)
* Add ability to set shell character encoding and set `TERM` environmental variable in the new Terminal module
* Add support for editing network interfaces in include files for Debian systems
* Add various improvements to the old good Framed Theme
* Fix to change Gray Framed Theme name to Framed Theme
* Fix to verify and close WebSocket session, if parent session was closed
* Fix to remove `RC4` from the list of strong ciphers
* Fix don't fail LDAP user or group deletion, if they have already been deleted
* Fix error handling in MySQL/MariaDB Database server module when executing SQL commands
* Fix adding an extra server attachment field and other bugs in Read User Mail module
* Fix the link to release notes for Rocky Linux
* Fix issues with freezing and thawing dynamic reverse zones in BIND DNS Server module
* Fix bugs for modules granting anonymous access
* Fix `mailbox_idle_check_interval` option related bugs in Dovecot module [sourceforge.net#5602](https://sourceforge.net/p/webadmin/bugs/5602/)
* Fix to use correct extension for package file when upgrading Webmin [webmin/authentic-theme#1633](https://github.com/webmin/authentic-theme/issues/1633)
* Update the Authentic theme to the latest version
#### 2.010 (November 27, 2022)
* Add a new Terminal module (interactive shell)
* Add a new `setup-repos.sh` script to setup Webmin repos
* Add to replace old Gray Theme with Virtualmin Framed Theme
* Add _systemd_ improvements
* Add proper support for openSUSE Leap and Tumbleweed
* Add Linux Lite support
* Fix connecting to external IPv6 LDAP server
* Fix self-signed certificate generation
* Fix setting hostname using `hostnamectl` command on _systemd_ systems
* Fix to exclude sensors with unknown temperatures
* Fix for FreeBSD to support Let's Encrypt certificates requests
* Fix to support attachment filenames with slash in them
#### 2.001 (September 18, 2022)
* Fix missing origins and action for direct rules in FirewallD module
* Removed the need for a full restart when updating SSH keys
* Improved the Javascript for redirects to HTTPS
#### 2.000 (August 21, 2022)
* Add to enforce HTTP Strict Transport Security (HSTS) policy in SSL enabled mode
* Add better `http` to `https` redirects when SSL is enabled
* Add support for installing multiple versions of Webmin on `systemd` systems
* Add support for AMD CPU thermisters #1714
* Add better support for Webmin minor (release) versions upgrades
* Add Webmin and Usermin configuration modules display minor (release) version
* Add Mint Linux support
* Add latest Authentic 20.00 [theme update](https://github.com/webmin/authentic-theme/releases/tag/20.00) with number of bug fixes
* Fix to also restart dependent services (i.e. `fail2ban`) upon `firewalld` restart
* Fix to preserve service state for Webmin and Usermin upon package upgrades (i.e. don't start stopped)
* Fix Bind module config incorrectly updated upon Webmin upgrades on CentOS 7
#### 1.999 (August 4, 2022)
* Fix to allow IPv6 addresses for slaves in BIND module
* Fix to send `HUP` signal on reload with `systemd`
* Fix icons in Servers Index module for newer distros (Alma and Rocky)
* Fix to remove depricated option `UsePrivilegeSeparation` with OpenSSH 7.5+
* Fix Oracle Linux support
* Fix Ubuntu release notes links
* Add Webmin release note message
* Add latest Authentic [theme update](https://github.com/webmin/authentic-theme/releases/tag/19.99) with number of bug fixes
#### 1.998 (July 25, 2022)
* Fix Apache, BIND, MySQL, ProFTPd and other modules configs on newest distros for new installs
* Fix to use Cron default path when run from UI
* Fix post uninstall cleanups
* Fix version detection bug for Log File Rotation module
* Add improvements to Partitions on Local Disks module
* Add better support for CentOS Stream Linux for new installs
* Add improvements for searching and naming global PHP configs files
* Add support for unix extensions option for Samba module https://github.com/webmin/webmin/issues/1695
* Add latest Authentic [theme update](https://github.com/webmin/authentic-theme/releases/tag/19.98) with various bug fixes and small improvements
#### 1.997 (July 12, 2022)
* Add support for mirror and RAID volumes in LVM module
* Add latest Authentic [theme update](https://github.com/webmin/authentic-theme/releases/tag/19.97) with nice new features in File Manager and other fixes
* Fix more issues with restart when Webmin is upgraded from UI
#### 1.996 (July 4, 2022)
* Fix issues with `systemd` restarting Webmin on upgrade found in 1.995
#### 1.995 (June 23, 2022)
* Add improvements to stability for `systemd` systems
* Add native support to default to system default hashing format
* Add support to `yescrypt` password hashing scheme
* Add new _System Logs Viewer_ (logviewer) module
* Add new `webmin server` sub-command
* Add to set environmental variables in Filesystem Backup module
* Fix upload tracker issues with large uploads
* Fix NVMe drives status support
* Fix AlmaLinux support
* Fix BIND config for FreeBSD 12 on initial setup
#### Version 1.994 (May 22, 2022)
This release fixes a security issue in versions 1.991 and below. All systems with less-privileged Webmin users are recommended to upgrade as soon as possible.
#### Version 1.991 (April 18, 2022)
This is mainly a bugfix release for issues found since 1.990.
#### Version 1.990 (March 3, 2022)
This release contains a critical security fix, an updated theme, and a bunch of other small features and improvements. We recommend that all systems with untrusted Webmin users upgrade immediately!
#### Version 1.983 (December 26, 2021)
This release is mostly bugfixes for issues found in 1.983.
#### Version 1.983 (December 4, 2021)
These releases are mostly bugfixes for issues found in 1.982.
#### Version 1.982 (November 26, 2021)
This release includes the latest Authentic theme, support for archive extraction and folder uploads in the File Manager module, automatic formatting of the Apache config, translation updates, and many more small features and bugfixes.
#### Version 1.981 (August 28, 2021)
This is just a bugfix for issues found in version 1.980.
#### Version 1.980 (August 22, 2021)
This release includes numerous small bugfixes, a theme update, translation fixes, support for Rocky and Alma Linuxes, and a new API for changing password.
#### Version 1.979 (June 15, 2021)
This release fixes several bugs found in 1.974, updates the Authentic theme, adds 2FA support in Usermin, and fixes a security bug in the Network Configuration module.
#### Version 1.974 (May 1, 2021)
Mostly a bugfix release, but it also contains a security for users who installed using the `setup.pl` script (which is not common).
#### Version 1.972 (March 1, 2021)
This is mainly a bugfix release for issues with Let's Encrypt and a few other modules.
#### Version 1.970 (January 6, 2021)
This release updates the theme, fixes a Windows security issue, updates the CA cert for Let's Encrypt, and improves translations.
#### Version 1.962 (November 11, 2020)
These are bugfix releases for 2-factor signin and other small issues.
#### Version 1.960 (October 19, 2020)
This release improves MySQL user management, updates the theme UI, fixes parsing of complex Netplan configs, removes the dependency on apt-show-versions and much much more.
#### Version 1.953 (July 5, 2020)
This release adds automatic translations for all languages in UTF-8, updates the Authentic theme, adds support for Postfix SNI certs and Chrony, caching for LDAP lookups, and a huge number of bugfixes and minor features.
#### Version 1.941 (January 16, 2020)
This release updates the built-in Let's Encrypt client, adds support for creating "safe-mode" Webmin users, support for CAA records in the BIND module, and the ability to search Postfix maps. It also updates the Authentic theme to the latest version, which includes numerous improvements to the File Manager and overall UI.
#### Version 1.930 (August 18, 2019)
These updates fix a [security vulnerability](http://webmin.com/security.html) and should be installed IMMEDIATELY by all users. Although it is not exploitable in a Webmin install with the default configuration, upgrading is strongly recommended.
#### Version 1.920 (July 04, 2019)
This update includes the latest theme version, translation updates, the ability to disable hosts file entries, easier monitoring of bootup actions, and a bunch of bugfixes.
#### Version 1.910 (May 09, 2019)
This release includes theme and translation updates, a page for editing package repositories, cron and status module improvements, and a bunch of other bugfixes and small improvements.
#### Version 1.900 (November 19, 2018)
This version includes wildcard Let's Encrypt SSL cert support, theme and translation updates, support for announcements to Webmin users, and a bunch of other bugfixes and small improvements.
#### Version 1.890 (July 19, 2018)
This version includes Ubuntu 18 network config support, translation updates, multiple theme and file manager updates, BIND freeze/thaw support, support for more Linux distributuions, and a bunch of other bugfixes and small improvements.
#### Version 1.880 (March 16, 2018)
This version includes German, Catalan and Bulgarian translation updates, a new version of the Authentic theme, support for directly editing the MySQL and PostgreSQL config files, Let's Encrypt bugfixes, more control over system status email notifications, and more.
#### Version 1.870 (December 08, 2018)
This release includes many translation updates, fixes for Let's Encrypt support, UI cleanups, and most importantly a new major version of the Authentic theme.
#### Version 1.860 (October 10, 2017)
This release includes Let's Encrypt DNS fixes, Majordomo module improvements, XSS security bugfixes, translation updates, a new version of the theme, and more.
#### Version 1.850 (June 28, 2017)
This release includes Let's Encrypt fixes, Majordomo module improvements, FirewallD forwarding support, translation updates, an update to the Authentic theme, and a bunch of other bugfixes.
#### Version 1.840 (May 08, 2017)
This major release includes a large theme update, XSS security fixes, per-domain SSL cert support, thin-provisioned LVM support, Let's Encrypt improvements, translation updates, and the usual gang of bugfixes. Also available is Usermin 1.710, which contains many of the same updates.
#### Version 1.830 (December 29, 2016)
This is mainly a bugfix release, but also contains some translation updates, the latest version of the Authentic theme, fixes related to Let's Encrypt and LDAP client support, and SElinux and file attribute support in the file manager.
#### Version 1.820 (October 3, 2016)
This updated includes a bunch of bugfixes (particularly in the BIND module), translation updates, the ability to download a MySQL backup, Let's Encrypt improvements, and more.
#### Version 1.810 (August 8, 2016)
This updated includes the latest Authentic theme, a new IPv6 Firewall module for Linux, Webmin actions logging improvements, Let's Encrypt API fixes and a bunch of other small updates and bugfixes.
#### Version 1.800
* German translation updates, thanks to Raymond Vetter.
* Catalan translation updates from Jaume Badiella.
* Bulgarian translations from Grigor Gatchev.
* Added Support for Synology NAS and opkg/ipkg Community Package Manager, Kay Marquardt
* Added Support for configuring spam filtering when amvisd is used, Kay Marquardt
#### Version 1.790
* Added a recent logins section to the System Information page.
* Major rework of majordomo module, Kay Marquardt
#### Version 1.760
* For new installs, switched the location of data files in many modules to /var/webmin instead of /etc/webmin.
#### Version 1.750
* Norwegian updates, thanks to Stein-Aksel Basma.
* Catalan translation updates from Jaume Badiella.
* More German translation updates, thanks to Raymond Vetter.
* Fixed an XSS bug that allowed xmlrpc.cgi to be abused by a malicious link.
#### Version 1.740
* Norwegian updates, thanks to Stein-Aksel Basma.
* Catalan translation updates from Jaume Badiella.
* More German translation updates, thanks to Raymond Vetter.
#### Version 1.730
* More German translation updates, thanks to Raymond Vetter.
* Norwegian updates, thanks to Stein-Aksel Basma.
* The awesome new Authentic Theme by @iliajie is now included in the Webmin package.
* Catalan translation updates from Jaume Badiella.
#### Version 1.720
* Deprecated the old blue-theme in favor of the new gray-theme.
* Catalan translation updates from Jaume Badiella.
* More German translation updates, thanks to Raymond Vetter.
#### Version 1.710
* SSL v2 and v3 are now disabled by default at Webmin install time, to block the POODLE attack. They can be re-enabled on the SSL Encryption page of the Webmin Configuration module.
#### Version 1.700
* More German translation updates, thanks to Raymond Vetter.
* Catalan updates, thanks to Jaume Badiella.
* Added additional protected against Shellshock exploits made via the Webmin webserver.
#### Version 1.690
* More German translation updates, thanks to Raymond Vetter.
* Support for RHEL 7, CentOS 7 and other derivatives in multiple modules.
#### Version 1.670
* More German translation updates, thanks to Raymond Vetter.
* Norwegian updates, thanks to Stein-Aksel Basma.
* Catalan updates, thanks to Jaume Badiella.
* Security fixes for XSS attacks in `user_chooser.cgi` and other scripts.
#### Version 1.660
* More German translation updates, thanks to Raymond Vetter.
* Norwegian updates, thanks to Stein-Aksel Basma.
* Catalan updates, thanks to Jaume Badiella.
* IPv6 access control now match an address exactly, unless a network size is entered.
* FTP uploads and downloads to IPv6-only servers now work properly, thanks to support for the EPSV protocol command.
* Added a Bahasa Malaysia translation, thanks to Nawawi Jamili, Nizam Adnan and Weldan Jamili.
* Added filtering for lists in the user, group and file chooser popups, thanks to a patch from Nawawi Jamili.
#### Version 1.650
* More German translation updates, thanks to Raymond Vetter.
* Norwegian updates, thanks to Stein-Aksel Basma.
#### Version 1.620
* More German translation updates, thanks to Raymond Vetter.
* Polish translation updates from Piotr Kozica.
* Norwegian updates, thanks to Stein-Aksel Basma.
* Improved FreeBSD 8 and 9 support across multiple modules.
* Hungarian translation updates from Balázs Zoltán.
#### Version 1.610
* Norwegian updates, thanks to Stein-Aksel Basma.
* Catalan updates, thanks to Jaume Badiella.
* Yet more German translation updates, thanks to Raymond Vetter.
* Polish translation updates from Piotr Kozica.
#### Version 1.600
* Even more German translation updates, thanks to Raymond Vetter.
* Catalan updates, thanks to Jaume Badiella.
#### Version 1.590
* Even more German translation updates, thanks to Raymond Vetter.
* Norwegian updates, thanks to Stein-Aksel Basma.
* Dutch translation updates, thanks to Gandyman.
* Switch order of command and mode in debug logs to make it clear that "mode=X" is part of the log, not part of the command.
* Added the new Gray Framed Theme, and made it the default for new installs.
#### Version 1.580
* Even more German translation updates, thanks to Raymond Vetter.
* More Dutch updates, thanks to Gandyman.
* Catalan updates, thanks to Jaume Badiella.
* Norwegian updates, thanks to Stein-Aksel Basma.
* All languages now have UTF-8 encoded variants, as well as their native character sets.
* Added support for Ubuntu 12.04.
#### Version 1.570
* Even more German translation updates, thanks to Raymond Vetter.
* Added UTF-8 encodings for languages using the iso-8859-2, like Czech and Polish.
* Catalan updates, thanks to Jaume Badiella.
* Norwegian translation updates, thanks to Stein-Aksel Basma.
* The MySQL, PostgreSQL, Filesystem Backup and Backup Configuration Files modules now all support the use of Webmin variable substitutions in backup paths (like $HOSTNAME) via a new Module Config option.
#### Version 1.560
* More German translation updates, thanks to Raymond Vetter.
* More French translation updates, thanks to ButterflyOfFire.
#### Version 1.550
* Catalan updates, thanks to Jaume Badiella.
* Italian translation updates, thanks to Andrea Oliveri.
* Major German translation updates, thanks to Raymond Vetter.
#### Version 1.530
* Speed up the loading of language files by pre-caching them in memory when Webmin is started, and not performing sub-string substitutions in most modules.
* Added support for Pardus Linux, thanks to Kaan Ozdincer.
* Major Dutch updates, thanks to Gandyman.
* Majoe French translation update, thanks to ButterflyOfFire.
* Allow per-language language overrides to be defined, in custom-lang.$code files.
* Updated numerous modules to improve support for Debian 6 and Ubuntu 10.10.
* If a browser asks for gzip compression, Webmin can now return compressed content either generated dynamically or from a pre-compressed .gz file in the same directory. Dynamic compression depends on the Compress::Zlib perl module.
* Added support for Amazon Linux.
#### Version 1.520
* Catalan translation updates by Jaume Badiella.
#### Version 1.510
* Dutch translation updates, thanks to Gandyman.
* Polish translation updates, thanks to Dariusz Dêbowski.
#### Version 1.500
* Czech translation updates, thanks to Karel Hudan.
* The Webmin RPM now preserves the /etc/webmin directory when un-installed and then re-installed.
* Added a robots.txt file to block indexing of Webmin by search engines.
* The Webmin search box can now be disabled in the Webmin Users module, under "Permissions for all modules".
* Brazillian Portuguese translation updates for several modules, thanks to Djavan Fagundes.
#### Version 1.480
* Catalan translation updates by Jaume Badiella.
* Dutch translation updates, thanks to Gandyman.
* Beginnings of a Basque translation, thanks to Mireia Lezea.
#### Version 1.470
* Catalan translation updates by Jaume Badiella.
* Added an UTF-8 encoding of the Russian translation, thanks to shavlukov@gmail.com.
* French translation updates by ButterflyOfFire.
* Dutch translation updates by Gandyman.
* Dramatically improved Webmin's search function, to include links to pages that help or UI text comes from. Also changed the layout of results to a more Webmin-ish style.
#### Version 1.450
* Added a language option for UK english, and converted words in the default Webmin language to US english.
* Major Dutch translation updates, thanks to Gandyman.
* Catalan translation updates by Jaume Badiella.
* Converted all core modules to use the new WebminCore perl module instead of `web-lib.pl`. This significantly improves memory use and load time in code that uses functions from multiple modules, asssuming they have all been converted.
#### Version 1.440
* Russian translation updates, thanks to Anton Statutov.
* Webmin's serialization functions can now handle objects, which allows them to be passed as parameters to remote function calls. Both caller and recipient must have the object's class installed though.
* Converted commands in the core `web-lib-funcs.pl` API file to POD format, and added more details about each function.
#### Version 1.430
* A large Croatian translation update, thanks to Domagoj Bikic.
* When a user whose password is close to expiry or has already expired logs in, a warning will be displayed on Webmin's first page.
* Many Japanese translation updates, thanks to Kazuya Masuda.
#### Version 1.420
* Many Greek translation updates, thanks to Vagelis Koutsomitros.
* Catalan translation updates by Jaume Badiella.
* Many Dutch translation contributions by Gandyman.
#### Version 1.410
* Many Korean updates, thanks to JoungKyun Kim.
* More Dutch updates, thanks to Gandyman.
* Added a debugging log file, which records all files read and written, commands run and more. This can be enabled in the Webmin Configuration module.
#### Version 1.400
* Big Czech translation updates, thanks to Petr Vanek and the Czech translation team.
* All popups in Webmin are now XSS-safe, and thus do not need protection from unknown referers which prevented them from working in some browsers.
* All Webmin session IDs are now stored MD5 hashed, to prevent sessions from being captured if the sessiondb DBM is somehow read by an attacker.
* Many Dutch updates, thanks to Gandyman.
* MD5 encryption for Webmin and Unix passwords can be used on systems that have either the MD5 or Digest::MD5 perl module, or support it in the crypt() function.
#### Version 1.390
* Links from unknown referers are now blocked by default, to prevent XSS attacks. This may break browsers that don't supply a Referer: HTTP header.
#### Version 1.380
* Added a search box to the left frame of the blue theme, for finding modules, config options, help pages and text.
* All images, CSS and other static content served by Webmin has an HTTP Expires for 1 week in the future, to improve cachability.
* Lock files are automatically removed when the process creating them exits.
* NetBSD 4.0 support.
* Italian and Catalan translations contributed for many modules, thanks to Giovanni and Jaume Badiella.
* Changed the error message that appears when Webmin detects a link from another web page, and removed the button to allow the link (which was unreliable anyway).
#### Version 1.370
* Hid the Jabber and Security Sentries modules by default, as the underlying software is no longer supported.
* On Linux systems, sped up the function for finding processes so that it no longer has to launch 'ps' - instead, it reads /proc directly.
* When `read_file_lines` is used to read a file, the Unix or Windows newlines will be preserved when it is written out.
#### Version 1.340
* Added Redhat Enterprise release 5 support.
* Requests to the /unauthenticated URL can never execute CGI programs, to provide an extra layer of security against URL escaping attacks.
* Fixed XSS bugs in `pam_login.cgi`.
#### Version 1.330
* Added more `ui-lib.pl` functions for hidden page sections.
* Fixed another XSS bug in chooser.cgi.
* The Webmin function to get the system's hostname now reads a file instead of calling the hostname comment, which is faster.
* Added an ACL option to the file chooser for additional directories to allow access to.
* Changed the way sizes are displayed, to use a format like 1.32 GB or 8 kB.
* Removed letter images (used by the old theme), and forced the standard header function to always use text titles.
* Added support for Slam64 Linux.
#### Version 1.320
* Fixed XSS bugs in chooser.cgi.
* If the operating system is upgraded after Webmin is installed, a button is displayed on the main page to update Webmin's view of the current OS.
* Improved the tabs API to add an option to put a box around the visible tab, and whitespace around tabs.
* If listening on all specified IP addresses fails, Webmin will fall back to accepting connections on any address.
* All Module Config pages are now generating using new `ui-lib.pl` code, for easier theming.
* Added a global access control option to set the Unix user the file browser lists directories as.
#### Version 1.310
* Module configuration files can now be named based on the real operating system types, such as config-Ubuntu-Linux, which would be used in preference to config-debian-linux.
* When a large file is uploaded, it is no longer read into memory by `miniserv.pl`.
* Update the code that fetches mirror sites from Sourceforge, to handle their new website design.
* Changed the default theme for all installs to the new framed blue theme.
* Updated all rows of links (like select all, invert selection, add something) above tables to use a separator between links.
* Added caching for sudo capable user checks, to avoid excessive slow calls to sudo.
* Fixed a memory leak when running under ActiveState Perl on Windows.
#### Version 1.300
* Fixed the rare bug about renaming the .webmintmp file.
#### Version 1.290
* SELinux security contexts are preserved on files safely modified by Webmin's write-and-rename code.
* Added xmlrpc.cgi program, which provides an XML-RPC interface to all Webmin module functions.
* Tested and improved support for Fedora 5.
#### Version 1.280
* Fixed security holes that allow remote read access to any file on the server for which the path is known.
#### Version 1.270
* Updated almost all modules that use tables to use the new `ui_columns` functions. This allows themes to do highlighting when a row is moved over or selected.
* Added a new 'Simple Blue' theme, which uses fewer images and does table row highlighting.
* Changed the way that Webmin log diff files are stored, so that they are categorized by action and not all in one huge directory.
#### Version 1.260
* Proxy settings made in the Webmin Configuration module are passed on to programs Webmin calls via the `http_proxy` and `ftp_proxy` environment variables.
* Added automatically created UTF-8 translations for simplified and traditional Chinese.
#### Version 1.240
* Fixed a possible security hole caused by a bug in Perl.
#### Version 1.230
* Replaced all calls to the crypt() function with new code that will use the Crypt::UnixCrypt Perl modules on systems for with crypt() is broken.
#### Version 1.220
* Added basic support for running Webmin on Windows system with ActiveState Perl installed. The new `setup.pl` install script must be used, as the setup.sh shell script cannot run on Windows.
* Fixed a bug that could allow a remote attack if the option to use full PAM conversations is enabled.
* Improved the Webmin RPM to not lose the /etc/webmin directory when upgrading from an RPM by another vendor (like Mandrake or DAG).
#### Version 1.210
* Added a new Global ACL control option to limit a user to read-only mode. This does not yet support all modules, but in those that are supported any changes the user makes will simply not take effect.
* Restarting of Webmin is now much faster in some modules that do not need a full configuration reload, due to the addition of a function that justs tells `miniserv.pl` to re-read its config file.
#### Version 1.200
* On Solaris systems that support RBAC, available modules and access rights can now be derived from RBAC for selected users. This can be enabled on a per-user or per-module basic in the Webmin Users module.
#### Version 1.180
* All subheadings have been reduced in size when using the default MSC theme.
* All modules now use a new API for writing to configuration files, which ensures that the file does not get written to or truncated if the system is out of disk space.
#### Version 1.170
* When installing a module from the command line, by it will be granted to the same users who receive new modules when Webmin is upgraded. By default, this is root and admin.
* Added basic support for multiple root directories, so that Webmin modules can be separated into core and third-party on the filesystem.
* When installing or upgrading Webmin, password timeouts are now enabled by default. This protects against brute-force password guessing attacks.
#### Version 1.160
* Added support for Solaris 10.
* Included several additional translations for various languages and modules.
* Added support for config- files that allow a range of OS version numbers, and used this to reduce the number of standard config files.
#### Version 1.150
* Updated the setup.sh script to use MD5 password encryption by default, on systems where Perl supports it.
* Fixed a security hole in the `maketemp.pl` script, used to create the /tmp/.webmin directory at install time. If an un-trusted user creates this directory before Webmin is installed, he could create in it a symbolic link pointing to a critical file on the system, which would be overwritten when Webmin writes to the link filename (CVE bug CAN-2004-0559).
* When PAM is used for Unix authentication, expired passwords are now detected and the user is prompted to select a new password (if this feature is enabled on the Webmin Configuration module).
* Make all functions in `ui-lib.pl` themable, allowing themes to have more detailed control over modules that make use of this library.
* Updated all modules to call `ui_print_header` instead of calling header and printing `<hr>`, so that themes can avoid the `<hr>`. Also updated the MSC theme to do this.
#### Version 1.140
* Fixed a security hole that allowed any user to view the configuration of any module, even those that they should not have access to.
* Fixed a security hole that could allow an attacker to lock valid users by sending a bogus username or password.

30
LICENCE Normal file
View File

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

30
LICENCE.ja Normal file
View File

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

225
OsChooser.pm Executable file
View File

@@ -0,0 +1,225 @@
#!/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

53
README-zh.md Normal file
View File

@@ -0,0 +1,53 @@
## 内容
* [更新日志](https://github.com/webmin/webmin/blob/master/CHANGELOG.md)
* [关于](#关于)
* [安装](#安装)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-stable.png?raw=true" title="稳定版">](http://webmin.com/download.html)[<img src="https://github.com/webmin-devel/webmin/blob/master/media/download-23x14-devel.png?raw=true" title="Development Versions">](http://webmin.com/devel.html)
* [文档](#文档)
* [致谢](#致谢)
* [许可](#许可)
## 关于
**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 和 [其他发行版](http://www.webmin.com/support.html))。[下载页面直达车](http://webmin.com/download.html);
<kbd>注:非常建议[在你的系统添加源](https://doxfer.webmin.com/Webmin/Installation),这样可以自动更新</kbd>
2. 下载并解压[源码](https://prdownloads.sourceforge.net/webadmin/webmin-1.996.tar.gz)然后运行[_setup.sh_](http://www.webmin.com/tgz.html) 脚本,无需任何选项,也就是说会直接安装到当前目录。或者使用命令行参数,例如目标目录。
<kbd>注:如果你正在安装 Webmin [到Windows](http://www.webmin.com/windows.html) 系统上,你必须运行 `perl setup.pl` 命令。Windows 版能否正常运行取决于许多程序,和可能不属于标准发行版的模块。你需要 _process.exe_ 命令, _sc.exe_ 命令,以及 _Win32::Daemon_ Perl 模块。</kbd>
## 文档
完整的 Webmin 还有它所有模块的详细配置都在[维基页面](https://doxfer.webmin.com/Webmin/Main_Page).
## 致谢
### 首席开发者
* [Jamie Cameron](http://www.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/iliajie)
* [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)发布。

61
README.md Normal file
View File

@@ -0,0 +1,61 @@
&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/#gh-light-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218264253-c08fb45a-8d75-44bf-93b3-37a2ecae3d20.png">
</a>
<a href="https://webmin.com/screenshots/#gh-dark-mode-only" target="_blank">
<img width="1440" alt="Dashboard screenshot" src="https://user-images.githubusercontent.com/4426533/218265232-31140aa6-ada1-4019-bd75-04240aeabc83.png">
</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://www.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/iliajie)
* [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).

23
SECURITY.md Normal file
View File

@@ -0,0 +1,23 @@
## Reporting Security Issues
Please send all reports of security issues found in Webmin to security@webmin.com
via email, ideally PGP encrypted with the key from https://www.webmin.com/jcameron-key.asc .
Potential security issues, in descending order of impact, include :
* Remotely exploitable attacks that allow `root` access to Webmin without
any credentials.
* Privilege escalation vulnerabilities that allow non-`root` users of Webmin
to run commands or access files as `root`.
* XSS attacks that target users already logged into Webmin when they visit
another website.
Things that are not actually security issues include :
* XSS attacks that are blocked by Webmin's referrer checks, which are enabled
by default.
* Attacks that require modifications to Webmin's code or configuration, which
can only be done by someone who already has `root` permissions.

39
WebminCore.pm Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

68
acl/CHANGELOG Normal file
View File

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

2316
acl/acl-lib.pl Executable file

File diff suppressed because it is too large Load Diff

87
acl/acl_security.pl Executable file
View File

@@ -0,0 +1,87 @@
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');
}

108
acl/backup_config.pl Executable file
View File

@@ -0,0 +1,108 @@
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require 'acl-lib.pl';
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 undef;
}
# 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 undef;
}
# 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 undef;
}
# 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 undef;
}
1;

56
acl/cert_form.cgi Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/local/bin/perl
# cert_form.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
our (%in, %text, %config, %access);
&ui_print_header(undef, $text{'cert_title'}, "", undef, undef, undef, undef,
undef, undef, "language=VBSCRIPT onload='postLoad()'");
eval "use Net::SSLeay";
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'});

58
acl/cert_issue.cgi Executable file
View File

@@ -0,0 +1,58 @@
#!/usr/local/bin/perl
# cert_issue.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
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);
}

19
acl/cert_output.cgi Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/local/bin/perl
# cert_issue.cgi
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
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'});

31
acl/cgi_args.pl Executable file
View File

@@ -0,0 +1,31 @@
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 undef;
}

4
acl/config Normal file
View File

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

3
acl/config-ALL-linux Normal file
View File

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

3
acl/config-freebsd Normal file
View File

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

3
acl/config-macos Normal file
View File

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

3
acl/config-netbsd Normal file
View File

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

3
acl/config-openbsd Normal file
View File

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

View File

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

4
acl/config-syno-linux Normal file
View File

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

5
acl/config.info Normal file
View File

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

5
acl/config.info.ar Normal file
View File

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

5
acl/config.info.bg Normal file
View File

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

5
acl/config.info.ca Normal file
View File

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

5
acl/config.info.cs Normal file
View File

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

5
acl/config.info.da Normal file
View File

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

5
acl/config.info.de Normal file
View File

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

5
acl/config.info.es Normal file
View File

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

5
acl/config.info.eu Normal file
View File

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

5
acl/config.info.fa Normal file
View File

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

5
acl/config.info.fr Normal file
View File

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

0
acl/config.info.hr Normal file
View File

5
acl/config.info.hu Normal file
View File

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

5
acl/config.info.it Normal file
View File

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

5
acl/config.info.ja Normal file
View File

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

5
acl/config.info.ko Normal file
View File

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

5
acl/config.info.ms Normal file
View File

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

5
acl/config.info.nl Normal file
View File

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

5
acl/config.info.no Normal file
View File

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

5
acl/config.info.pl Normal file
View File

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

5
acl/config.info.pt_BR Normal file
View File

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

5
acl/config.info.ru Normal file
View File

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

5
acl/config.info.sk Normal file
View File

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

1
acl/config.info.sv Normal file
View File

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

5
acl/config.info.tr Normal file
View File

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

4
acl/config.info.uk Normal file
View File

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

1
acl/config.info.zh Normal file
View File

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

4
acl/config.info.zh_TW Normal file
View File

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

150
acl/convert.cgi Executable file
View File

@@ -0,0 +1,150 @@
#!/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';
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'});

54
acl/convert_form.cgi Executable file
View File

@@ -0,0 +1,54 @@
#!/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';
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'});

28
acl/defaultacl Normal file
View File

@@ -0,0 +1,28 @@
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
rbacenable=1
logouttime=1
times=1
minsize=1
nochange=1
pass=1
sql=1

54
acl/delete_group.cgi Executable file
View File

@@ -0,0 +1,54 @@
#!/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';
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("");
}

63
acl/delete_groups.cgi Executable file
View File

@@ -0,0 +1,63 @@
#!/usr/local/bin/perl
# Delete a bunch of Webmin groups
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
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'});
}

20
acl/delete_session.cgi Executable file
View File

@@ -0,0 +1,20 @@
#!/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';
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");

24
acl/delete_user.cgi Executable file
View File

@@ -0,0 +1,24 @@
#!/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';
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("");

112
acl/delete_users.cgi Executable file
View File

@@ -0,0 +1,112 @@
#!/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';
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'});
}

89
acl/edit_acl.cgi Executable file
View File

@@ -0,0 +1,89 @@
#!/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';
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);
if ($in{'mod'} && $in{'user'} && &supports_rbac($in{'mod'}) &&
!$gconfig{'rbacdeny_'.$who}) {
# Show RBAC option
print &ui_table_row($text{'acl_rbac'},
&ui_radio("rbac", $maccess{'rbac'} ? 1 : 0,
[ [ 1, $text{'acl_rbacyes'} ],
[ 0, $text{'no'} ] ]), 3);
}
# Load custom ACL library
my $mdir = &module_root_directory($in{'mod'});
if (-r "$mdir/acl_security.pl") {
&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'});

152
acl/edit_group.cgi Executable file
View File

@@ -0,0 +1,152 @@
#!/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';
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'});

59
acl/edit_pass.cgi Executable file
View File

@@ -0,0 +1,59 @@
#!/usr/local/bin/perl
# Show password quality and change restrictions
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
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'});

32
acl/edit_rbac.cgi Executable file
View File

@@ -0,0 +1,32 @@
#!/usr/local/bin/perl
# Show RBAC status
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
our (%in, %text, %gconfig, %access, $module_name, $module_root_directory);
$access{'rbacenable'} || &error($text{'rbac_ecannot'});
&ui_print_header(undef, $text{'rbac_title'}, "");
print "$text{'rbac_desc'}<p>\n";
if ($gconfig{'os_type'} ne 'solaris') {
print &text('rbac_esolaris', $gconfig{'real_os_type'}),"<p>\n";
}
elsif (!&supports_rbac()) {
if (&foreign_available("cpan")) {
print &text('rbac_eperl', "<tt>Authen::SolarisRBAC</tt>",
"../cpan/download.cgi?source=0&local=$module_root_directory/Authen-SolarisRBAC-0.1.tar.gz&mode=2&return=/$module_name/&returndesc=".&urlize($text{'index_return'})),"<p>\n";
}
else {
print &text('rbac_ecpan', "<tt>Authen::SolarisRBAC</tt>"),
"<p>\n";
}
}
else {
print "$text{'rbac_ok'}<p>\n";
}
&ui_print_footer("", $text{'index_return'});

114
acl/edit_sql.cgi Executable file
View File

@@ -0,0 +1,114 @@
#!/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';
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'});

44
acl/edit_sync.cgi Executable file
View File

@@ -0,0 +1,44 @@
#!/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';
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'});

91
acl/edit_unix.cgi Executable file
View File

@@ -0,0 +1,91 @@
#!/usr/local/bin/perl
# edit_unix.cgi
# Choose a user whose permissions will be used for logins that don't
# match any webmin user, but have unix accounts
use strict;
use warnings;
no warnings 'redefine';
no warnings 'uninitialized';
require './acl-lib.pl';
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);
# Enable Unix auth
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 { [ $_->{'name'} ] }
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();
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", 40));
print &ui_table_end();
print &ui_form_end([ [ undef, $text{'save'} ] ]);
&ui_print_footer("", $text{'index_return'});

465
acl/edit_user.cgi Executable file
View File

@@ -0,0 +1,465 @@
#!/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';
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);
# 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));
# 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 "use DateTime; use DateTime::Locale; use DateTime::TimeZone;";
if (!$@) {
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'}) {
# 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) ] ]));
}
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'} ||
&supports_rbac() && $access{'mode'} == 0 || $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 (&supports_rbac() && $access{'mode'} == 0) {
# Deny access to modules not managed by RBAC?
print &ui_table_row($text{'edit_rbacdeny'},
&ui_radio("rbacdeny", $user{'rbacdeny'} ? 1 : 0,
[ [ 0, $text{'edit_rbacdeny0'} ],
[ 1, $text{'edit_rbacdeny1'} ] ]));
}
if ($access{'times'}) {
# Show allowed days of the week
my %days = map { $_, 1 } split(/,/, $user{'days'} || '');
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"));
}
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) {
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) {
# 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 && $in{'user'} && !$safe) {
print &ui_hidden_table_start($text{'edit_global'}, "width=100%", 2,
"global", 0, [ "width=30%" ]);
my %uaccess;
%uaccess = &get_module_acl($in{'user'}, "", 1);
print &ui_hidden("acl_security_form", 1);
&foreign_require("", "acl_security.pl");
&foreign_call("", "acl_security_form", \%uaccess);
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 ($access{'delete'}) {
push(@buts, [ "but_delete", $text{'delete'} ]);
}
}
print &ui_form_end(\@buts);
&ui_print_footer("", $text{'index_return'});

19
acl/feedback_files.pl Executable file
View File

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

@@ -0,0 +1 @@
<header> IP-toegangsbeheer </header> Gebruiker-IP-toegangsbeheer werk op dieselfde manier as die globale IP-toegangsbeheer in die Webmin Configuration-module. Slegs as &#39;n gebruiker die globale beheermaatreëls deurgaan, sal ook diegene hier gekontroleer word. <p><footer>

View File

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

View File

@@ -0,0 +1 @@
<header> Кантроль доступу IP </header> Карыстальніцкі кантроль доступу да IP працуе гэтак жа, як глабальны кантроль доступу да IP у модулі канфігурацыі Webmin. Толькі калі карыстальнік пройдзе глабальныя элементы кіравання, праверка будзе праверана і тут. <p><footer>

View File

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

8
acl/help/ips.ca.html Normal file
View File

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

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

5
acl/help/ips.da.html Normal file
View File

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

5
acl/help/ips.de.html Normal file
View File

@@ -0,0 +1,5 @@
<header>IP-Zugriffskontrolle</header>
Die Benutzer IP-Zugriffskontrolle funktioniert nach dem selben Prinzip wie die globale IP-Zugriffskontrolle im Webminkonfiguration-Modul. Nur wenn ein Benutzer durch die globalen IP-Zugriffskontrollen Zugang erhält wird zusätzlich die benutzerdefinierte IP-Zugriffkontrolle angewendet.
<footer>

View File

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

View File

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

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

17
acl/help/ips.fa.html Normal file
View File

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

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

5
acl/help/ips.fr.html Normal file
View File

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

@@ -0,0 +1 @@
<header> בקרת גישת IP </header> בקרת גישת IP של משתמשים פועלת באותו אופן כמו בקרת הגישה הגלובלית ל- IP במודול תצורת Webmin. רק אם משתמש יעבור את הפקדים הגלובליים ייבדקו גם אלה כאן. <p style=";text-align:right;direction:rtl"><footer>

View File

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

6
acl/help/ips.html Normal file
View File

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

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

5
acl/help/ips.it.html Normal file
View File

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

View File

@@ -0,0 +1 @@
<header> IPアクセス制御</header>ユーザーIPアクセス制御は、Webmin構成モジュールのグローバルIPアクセス制御と同じように機能します。ユーザーがグローバルコントロールに合格した場合のみ、ここでもチェックされます。 <p><footer>

6
acl/help/ips.ko.html Normal file
View File

@@ -0,0 +1,6 @@
<header>IP 접근 제어</header>
유저 IP 접근 제어 작업은 웹민 설정 모듈의 광역 IP 접근 제어와 같은 방법으로 작업 합니다.
광역 조절에서 통과된 유저는 여기에서 다시 체크가 되어집니다.
<footer>

View File

@@ -0,0 +1 @@
<header> IP prieigos kontrolė </header> Vartotojo IP prieigos kontrolė veikia taip pat, kaip ir pasaulinė IP prieigos kontrolė „Webmin Configuration“ modulyje. Tik tada, kai vartotojas perduos pasaulinius valdiklius, bus tikrinami ir šie. <p><footer>

View File

@@ -0,0 +1 @@
<header> IP piekļuves kontrole </header> Lietotāja IP piekļuves kontrole darbojas tāpat kā globālā IP piekļuves kontrole Webmin konfigurācijas modulī. Tikai tad, ja lietotājs nokārtos globālās vadīklas, tiks pārbaudītas arī šeit esošās. <p><footer>

5
acl/help/ips.ms.html Normal file
View File

@@ -0,0 +1,5 @@
<header>Kawalan capaian IP</header>
kawalan capaian IP pengguna berfungsi sama seperti kawalan capaian IP global dalam modul Konfigurasi Webmin. Hanya jika pengguna melepasi kawalan global baru diperiksa disini. <p>
<footer>

View File

@@ -0,0 +1 @@
<header> Kontroll tal-aċċess għall-IP </header> Il-kontroll ta &#39;l-aċċess ta&#39; l-IP għall-utent jaħdem bl-istess mod bħall-kontroll ta &#39;aċċess IP globali fil-modulu tal-Konfigurazzjoni Webmin. Biss jekk utent jgħaddi l-kontrolli globali dawk li hawn ukoll jiġu kkontrollati. <p><footer>

7
acl/help/ips.nl.html Normal file
View File

@@ -0,0 +1,7 @@
<header>IP toegangs controle</header>
Gebruiker IP toegangs controle werkt op dezelfde manier als de globale IP toegangs controle in de Webmin Configuratie module.
Alleen wanneer een gebruiker de globale controle passeerd zal hetgeen wat hier geconfigureerd is ook worden gecheckt. <p>
<footer>

5
acl/help/ips.no.html Normal file
View File

@@ -0,0 +1,5 @@
<header>IP tilgangskontroll</header>
Bruker IP tilgangskontroll virker på samme måte som global IP tilgangskontroll i Webmin konfigurasjonsmodulen. Bare de brukere som slipper gjennom den globale tilgangskontrollen vil bli kontrollert mot reglene her. <p>
<footer>

5
acl/help/ips.pl.html Normal file
View File

@@ -0,0 +1,5 @@
<header>Kontrola dostępu IP</header>
Kontrola dostępu IP działa tak samo jak globalna kontrola dostępu IP dostępna w module Konfiguracja Webmina. Jeśli użytkownik przejdzie przez kontrolę globalną będzie także sprawdzony tutaj.<p>
<footer>

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