Compare commits
134 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1d7d32130a | ||
|
|
9babcde3e5 | ||
|
|
9ec76c9fd6 | ||
|
|
61dfeb947f | ||
|
|
6fdf2636fc | ||
|
|
0a38d1ab5f | ||
|
|
7c80dc3d1d | ||
|
|
5ab49e3f50 | ||
|
|
06849133a8 | ||
|
|
4a912e3902 | ||
|
|
bcb95e9b7d | ||
|
|
c97f5f1e29 | ||
|
|
4d289e2a7f | ||
|
|
c491f2c03e | ||
|
|
5832346f75 | ||
|
|
4b4770ab36 | ||
|
|
8c998dd6f2 | ||
|
|
965359ec79 | ||
|
|
d1d42f2055 | ||
|
|
5f41b37770 | ||
|
|
61265778a5 | ||
|
|
8f0f890145 | ||
|
|
5ccae3f9bb | ||
|
|
f4d9e64804 | ||
|
|
149c0935fa | ||
|
|
cb0b537f6c | ||
|
|
b54c012579 | ||
|
|
389d83f5a3 | ||
|
|
00771381e8 | ||
|
|
46df429909 | ||
|
|
eb841da007 | ||
|
|
c4a2db03be | ||
|
|
e5838f00cf | ||
|
|
bcde7e93df | ||
|
|
bd8327afbe | ||
|
|
b961eba382 | ||
|
|
a552ea878e | ||
|
|
4ad2a1da1c | ||
|
|
37ae69f07a | ||
|
|
9870db2560 | ||
|
|
724a5e172a | ||
|
|
8e166cb842 | ||
|
|
5e281cf486 | ||
|
|
5d2f44ecd8 | ||
|
|
5009c625d8 | ||
|
|
eb592340b0 | ||
|
|
c6f556c8d9 | ||
|
|
db1df84ef1 | ||
|
|
52135a1d3a | ||
|
|
7f13bd09da | ||
|
|
7ccbb37c4e | ||
|
|
7feddf0aec | ||
|
|
e73523531a | ||
|
|
a47b790e19 | ||
|
|
319eec6124 | ||
|
|
21983f27b6 | ||
|
|
5d375b784d | ||
|
|
4b22470872 | ||
|
|
ec1c37aa06 | ||
|
|
67351ec3c2 | ||
|
|
f1887aaaf2 | ||
|
|
afd2d7b5e9 | ||
|
|
c967e585b5 | ||
|
|
73e364d4ba | ||
|
|
eb49331b21 | ||
|
|
0a1a3e023f | ||
|
|
bef5cedcd0 | ||
|
|
f8e2bc7bff | ||
|
|
09038ac7aa | ||
|
|
4c507232c7 | ||
|
|
86939a64da | ||
|
|
926ce427fc | ||
|
|
53401eebfb | ||
|
|
bef580929e | ||
|
|
c7b7c67ff4 | ||
|
|
ed42d4e3df | ||
|
|
69a2ebce36 | ||
|
|
15f08739fa | ||
|
|
571690c8c5 | ||
|
|
b2005d7f29 | ||
|
|
4354598c64 | ||
|
|
05d4bdc499 | ||
|
|
25c6a37df2 | ||
|
|
41a470fe36 | ||
|
|
8a4aa2a721 | ||
|
|
1d903770fc | ||
|
|
934be5a238 | ||
|
|
5608f0407f | ||
|
|
ce9d8dad7f | ||
|
|
d6fe263e68 | ||
|
|
156846a845 | ||
|
|
abe00b79a7 | ||
|
|
26ab659c6a | ||
|
|
b0273c68d2 | ||
|
|
720cf9d74f | ||
|
|
35cd567c48 | ||
|
|
2332d5be7b | ||
|
|
14cdc3801a | ||
|
|
d85efe480e | ||
|
|
4f2ceaa3ab | ||
|
|
3b6792d548 | ||
|
|
36de6e09d4 | ||
|
|
300c410b18 | ||
|
|
282d7d9101 | ||
|
|
48f6601003 | ||
|
|
c4c4279171 | ||
|
|
b88f9c1f18 | ||
|
|
0dac045dc9 | ||
|
|
80b5f97367 | ||
|
|
7a8b39fad0 | ||
|
|
9f5978e875 | ||
|
|
155fd757bf | ||
|
|
518ec202ab | ||
|
|
871083d613 | ||
|
|
79f0c8d28f | ||
|
|
dfbb4127e2 | ||
|
|
b9b2f00f30 | ||
|
|
6923f9d926 | ||
|
|
cacbf7fec7 | ||
|
|
73991e855c | ||
|
|
0208812013 | ||
|
|
48bd2561f7 | ||
|
|
af12c4102b | ||
|
|
d2efa3ecc4 | ||
|
|
acb04566f5 | ||
|
|
abb98ae960 | ||
|
|
0d202a7e4d | ||
|
|
c69ef20b17 | ||
|
|
5872d0682a | ||
|
|
c4fa8feb8c | ||
|
|
61a50cc657 | ||
|
|
3df3261ac0 | ||
|
|
f2636e14f0 | ||
|
|
a23f22f561 |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,6 +1,6 @@
|
||||
# Bug report vs. support request
|
||||
If you're unsure of whether your problem is a bug or a configuration error
|
||||
* contact us via IRC in #froxlor on freenode
|
||||
* contact us via IRC in #froxlor on irc.libera.chat
|
||||
* or post a thread in our forum at https://forum.froxlor.org
|
||||
|
||||
As a rule of thumb: before reporting an issue
|
||||
|
||||
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
40
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**As a rule of thumb: before reporting an issue**
|
||||
* see if it hasn't been [reported](https://github.com/Froxlor/froxlor/issues) (and possibly already been [fixed](https://github.com/Froxlor/froxlor/issues?utf8=✓&q=is:issue%20is:closed)) first
|
||||
* try with the git master
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**System information**
|
||||
* Froxlor version: $version/$gitSHA1
|
||||
* Web server: apache2/nginx/lighttpd
|
||||
* DNS server: Bind/PowerDNS (standalone)/PowerDNS (Bind-backend)
|
||||
* POP/IMAP server: Courier/Dovecot
|
||||
* SMTP server: postfix/exim
|
||||
* FTP server: proftpd/pureftpd
|
||||
* OS/Version: ...
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Logfiles**
|
||||
If applicable, add log-entries to help explain your problem.
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here.
|
||||
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
14
.github/workflows/build-apidocs.yml
vendored
Normal file
14
.github/workflows/build-apidocs.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: build-docs
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
|
||||
jobs:
|
||||
build_docs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- env:
|
||||
GITHUB_TOKEN: ${{ secrets.ORG_GITHUB_TOKEN }}
|
||||
run: |
|
||||
gh workflow run --repo Froxlor/Documentation build-docs -f ref=${{github.ref_name}}
|
||||
80
.github/workflows/build-mariadb.yml
vendored
Normal file
80
.github/workflows/build-mariadb.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
name: Froxlor-CI-MariaDB
|
||||
on: ['push', 'pull_request', 'create']
|
||||
|
||||
jobs:
|
||||
froxlor:
|
||||
name: Froxlor (PHP ${{ matrix.php-versions }}, MariaDB ${{ matrix.mariadb-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
mariadb-version: [10.5, 10.4]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP, with composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: composer:v2
|
||||
extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath
|
||||
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y ant
|
||||
|
||||
- name: Adjust firewall
|
||||
run: |
|
||||
sudo ufw allow out 3306/tcp
|
||||
sudo ufw allow in 3306/tcp
|
||||
|
||||
- name: Setup MariaDB
|
||||
uses: getong/mariadb-action@v1.1
|
||||
with:
|
||||
mariadb version: ${{ matrix.mariadb-version }}
|
||||
mysql database: 'froxlor010'
|
||||
mysql root password: 'fr0xl0r.TravisCI'
|
||||
|
||||
- name: Wait for database
|
||||
run: sleep 15
|
||||
|
||||
- name: Setup databases
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- name: Run testing
|
||||
run: ant quick-build
|
||||
|
||||
# - name: irc push
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'push'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} pushed ${{ github.event.ref }} ${{ github.event.compare }}
|
||||
# ${{ join(github.event.commits.*.message) }}
|
||||
|
||||
# - name: irc pull request
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'pull_request'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} opened PR ${{ github.event.pull_request.html_url }}
|
||||
|
||||
# - name: irc tag created
|
||||
# uses: rectalogic/notify-irc@v1
|
||||
# if: github.event_name == 'create' && github.event.ref_type == 'tag'
|
||||
# with:
|
||||
# channel: "#froxlor"
|
||||
# server: "irc.libera.chat"
|
||||
# nickname: froxlor-ci
|
||||
# message: |
|
||||
# ${{ github.actor }} tagged ${{ github.repository }} ${{ github.event.ref }}
|
||||
57
.github/workflows/build-mysql.yml
vendored
Normal file
57
.github/workflows/build-mysql.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
name: Froxlor-CI-MySQL
|
||||
on: ['push', 'pull_request', 'create']
|
||||
|
||||
jobs:
|
||||
froxlor:
|
||||
name: Froxlor (PHP ${{ matrix.php-versions }}, MySQL ${{ matrix.mysql-version }})
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
php-versions: ['7.4', '8.0']
|
||||
mysql-version: [8.0, 5.7]
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup PHP, with composer and extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
tools: composer:v2
|
||||
extensions: mbstring, xml, ctype, pdo_mysql, mysql, curl, json, zip, session, filter, posix, openssl, fileinfo, bcmath
|
||||
|
||||
- name: Install tools
|
||||
run: sudo apt-get install -y ant
|
||||
|
||||
- name: Adjust firewall
|
||||
run: |
|
||||
sudo ufw allow out 3306/tcp
|
||||
sudo ufw allow in 3306/tcp
|
||||
|
||||
- name: Setup MySQL
|
||||
uses: samin/mysql-action@v1.3
|
||||
with:
|
||||
mysql version: ${{ matrix.mysql-version }}
|
||||
mysql database: 'froxlor010'
|
||||
mysql root password: 'fr0xl0r.TravisCI'
|
||||
|
||||
- name: Wait for database
|
||||
run: sleep 15
|
||||
|
||||
- name: Setup database (8.0)
|
||||
if: matrix.mysql-version == '8.0'
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED WITH mysql_native_password BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- name: Setup database (5.7)
|
||||
if: matrix.mysql-version == '5.7'
|
||||
run: |
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "CREATE USER 'froxlor010'@'%' IDENTIFIED BY 'fr0xl0r.TravisCI';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI -e "GRANT ALL ON froxlor010.* TO 'froxlor010'@'%';"
|
||||
mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
|
||||
|
||||
- name: Run testing
|
||||
run: ant quick-build
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -12,9 +12,10 @@ logs/*
|
||||
.well-known
|
||||
.idea
|
||||
*.iml
|
||||
img/
|
||||
|
||||
!templates/Froxlor/
|
||||
!templates/Sparkle/
|
||||
!templates/misc/
|
||||
templates/Froxlor/assets/img/logo_custom.png
|
||||
templates/Sparkle/assets/css/custom.css
|
||||
vendor/
|
||||
|
||||
@@ -55,7 +55,7 @@ script:
|
||||
- ant phpunit-no-coverage
|
||||
|
||||
notifications:
|
||||
irc: "chat.freenode.net#froxlor"
|
||||
irc: "irc.libera.chat#froxlor"
|
||||
webhooks:
|
||||
urls:
|
||||
- https://webhooks.gitter.im/e/bdf91d1c3f745e51f796
|
||||
|
||||
25
README.md
25
README.md
@@ -1,5 +1,6 @@
|
||||
[](https://travis-ci.com/Froxlor/Froxlor)
|
||||
[](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
|
||||
[](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
|
||||
[](https://discord.froxlor.org)
|
||||
|
||||
# Froxlor
|
||||
|
||||
@@ -20,16 +21,20 @@ Developed by experienced server administrators, this panel simplifies the effort
|
||||
9. Have fun!
|
||||
|
||||
### Detailed installation
|
||||
https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball
|
||||
https://docs.froxlor.org/general/installation/index.html
|
||||
|
||||
## Help
|
||||
|
||||
You may find help in the following places:
|
||||
|
||||
### Discord
|
||||
|
||||
The froxlor community discord server can be found here: https://discord.froxlor.org
|
||||
|
||||
### IRC
|
||||
|
||||
froxlor may be found on freenode.net, channel #froxlor:
|
||||
irc://chat.freenode.net/froxlor
|
||||
froxlor may be found on libera.chat, channel #froxlor:
|
||||
irc://irc.libera.chat/froxlor
|
||||
|
||||
### Forum
|
||||
|
||||
@@ -37,12 +42,12 @@ The community is located on https://forum.froxlor.org/
|
||||
|
||||
### Wiki
|
||||
|
||||
More documentation may be found in the froxlor - wiki:
|
||||
https://github.com/Froxlor/Froxlor/wiki
|
||||
More documentation may be found in the froxlor - documentation:
|
||||
https://docs.froxlor.org/
|
||||
|
||||
## License
|
||||
|
||||
May be found in COPYING
|
||||
May be found in [COPYING](COPYING)
|
||||
|
||||
## Downloads
|
||||
|
||||
@@ -51,7 +56,7 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro
|
||||
|
||||
### Debian repository
|
||||
|
||||
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-debian)
|
||||
[HowTo](https://docs.froxlor.org/general/installation/aptpackage.html)
|
||||
|
||||
```
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates
|
||||
@@ -61,7 +66,7 @@ echo "deb https://deb.froxlor.org/debian $(lsb_release -sc) main" > /etc/apt/sou
|
||||
|
||||
### Ubuntu repository
|
||||
|
||||
[HowTo](https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-on-ubuntu)
|
||||
[HowTo](https://docs.froxlor.org/general/installation/aptpackage.html)
|
||||
|
||||
```
|
||||
apt-get -y install apt-transport-https lsb-release ca-certificates
|
||||
|
||||
@@ -77,14 +77,6 @@ return array(
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_no_robots' => array(
|
||||
'label' => $lng['serversettings']['no_robots'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'no_robots',
|
||||
'type' => 'bool',
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_paging' => array(
|
||||
'label' => $lng['serversettings']['paging'],
|
||||
'settinggroup' => 'panel',
|
||||
@@ -257,7 +249,7 @@ return array(
|
||||
'extras' => $lng['menue']['extras']['extras'],
|
||||
'extras.directoryprotection' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['directoryprotection'],
|
||||
'extras.pathoptions' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['pathoptions'],
|
||||
'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['logger']['logger'],
|
||||
'extras.logger' => $lng['menue']['extras']['extras'] . " / " . $lng['admin']['loggersystem'],
|
||||
'extras.backup' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['backup'],
|
||||
'traffic' => $lng['menue']['traffic']['traffic'],
|
||||
'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP",
|
||||
@@ -296,6 +288,40 @@ return array(
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_overridetheme' => array(
|
||||
'label' => $lng['serversettings']['logo_overridetheme'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_overridetheme',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_overridecustom' => array(
|
||||
'label' => $lng['serversettings']['logo_overridecustom'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_overridecustom',
|
||||
'type' => 'bool',
|
||||
'default' => false,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'panel_logo_image_header' => array(
|
||||
'label' => $lng['serversettings']['logo_image_header'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_image_header',
|
||||
'type' => 'image',
|
||||
'image_name' => 'logo_header',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingImage'
|
||||
),
|
||||
'panel_logo_image_login' => array(
|
||||
'label' => $lng['serversettings']['logo_image_login'],
|
||||
'settinggroup' => 'panel',
|
||||
'varname' => 'logo_image_login',
|
||||
'type' => 'image',
|
||||
'image_name' => 'logo_login',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingImage'
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -205,9 +205,21 @@ return array(
|
||||
'default' => false,
|
||||
'cronmodule' => 'froxlor/backup',
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
),
|
||||
'system_createstdsubdom_default' => array(
|
||||
'label' => $lng['serversettings']['createstdsubdom_default'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'createstdsubdom_default',
|
||||
'type' => 'option',
|
||||
'default' => '1',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'0' => $lng['panel']['no'],
|
||||
'1' => $lng['panel']['yes']
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -270,6 +270,20 @@ return array(
|
||||
'default' => true,
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_domaindefaultalias' => array(
|
||||
'label' => $lng['admin']['domaindefaultalias'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'domaindefaultalias',
|
||||
'type' => 'option',
|
||||
'default' => '0',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'0' => $lng['domains']['serveraliasoption_wildcard'],
|
||||
'1' => $lng['domains']['serveraliasoption_www'],
|
||||
'2' => $lng['domains']['serveraliasoption_none']
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'hide_incompatible_settings' => array(
|
||||
'label' => $lng['serversettings']['hide_incompatible_settings'],
|
||||
'settinggroup' => 'system',
|
||||
|
||||
@@ -133,6 +133,15 @@ return array(
|
||||
'cronmodule' => 'froxlor/letsencrypt',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_acmeshpath' => array(
|
||||
'label' => $lng['serversettings']['acmeshpath'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'acmeshpath',
|
||||
'type' => 'string',
|
||||
'string_type' => 'file',
|
||||
'default' => '/root/.acme.sh/acme.sh',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_letsencryptacmeconf' => array(
|
||||
'label' => $lng['serversettings']['letsencryptacmeconf'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -142,6 +151,9 @@ return array(
|
||||
'default' => '/etc/apache2/conf-enabled/acme.conf',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
/**
|
||||
* currently the only option anyway
|
||||
*
|
||||
'system_leapiversion' => array(
|
||||
'label' => $lng['serversettings']['leapiversion'],
|
||||
'settinggroup' => 'system',
|
||||
@@ -154,16 +166,20 @@ return array(
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
*/
|
||||
'system_letsencryptca' => array(
|
||||
'label' => $lng['serversettings']['letsencryptca'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'letsencryptca',
|
||||
'type' => 'option',
|
||||
'default' => 'production',
|
||||
'default' => 'letsencrypt',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)',
|
||||
'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)'
|
||||
'letsencrypt_test' => 'Let\'s Encrypt (Test / Staging)',
|
||||
'letsencrypt' => 'Let\'s Encrypt (Live)',
|
||||
'buypass_test' => 'Buypass (Test / Staging)',
|
||||
'buypass' => 'Buypass (Live)',
|
||||
'zerossl' => 'ZeroSSL (Live)'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
|
||||
@@ -99,6 +99,19 @@ return array(
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_powerdns_mode' => array(
|
||||
'label' => $lng['serversettings']['powerdns_mode'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'powerdns_mode',
|
||||
'type' => 'option',
|
||||
'default' => 'Native',
|
||||
'option_mode' => 'one',
|
||||
'option_options' => array(
|
||||
'Native' => 'Native',
|
||||
'Master' => 'Master'
|
||||
),
|
||||
'save_method' => 'storeSettingField'
|
||||
),
|
||||
'system_dns_createmailentry' => array(
|
||||
'label' => $lng['serversettings']['mail_also_with_mxservers'],
|
||||
'settinggroup' => 'system',
|
||||
|
||||
@@ -82,7 +82,20 @@ return array(
|
||||
'string_emptyallowed' => true,
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField'
|
||||
)
|
||||
),
|
||||
'system_froxlorusergroup' => array(
|
||||
'label' => $lng['serversettings']['froxlorusergroup'],
|
||||
'settinggroup' => 'system',
|
||||
'varname' => 'froxlorusergroup',
|
||||
'type' => 'string',
|
||||
'default' => '',
|
||||
'save_method' => 'storeSettingField',
|
||||
'plausibility_check_method' => array(
|
||||
'\\Froxlor\\Validate\\Check',
|
||||
'checkLocalGroup'
|
||||
),
|
||||
'visible' => \Froxlor\Settings::Get('system.nssextrausers')
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -129,7 +129,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
|
||||
'userid' => $userinfo['userid']
|
||||
));
|
||||
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
|
||||
`hash` = :hash, `userid` = :userid, `ipaddress` = :ip,
|
||||
|
||||
@@ -67,6 +67,9 @@ if ($page == 'showinfo') {
|
||||
$uptime_duration = duration($cache['start_time']);
|
||||
$size_vars = bsize($cache['mem_size']);
|
||||
|
||||
$num_hits_and_misses = $cache['num_hits'] + $cache['num_misses'];
|
||||
$num_hits_and_misses = 0 >= $num_hits_and_misses ? 1 : $num_hits_and_misses;
|
||||
|
||||
// check for possible empty values that are used in the templates
|
||||
if (! isset($cache['file_upload_progress'])) {
|
||||
$cache['file_upload_progress'] = $lng['logger']['unknown'];
|
||||
@@ -84,10 +87,10 @@ if ($page == 'showinfo') {
|
||||
|
||||
$freemem = bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size);
|
||||
$usedmem = bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 100 / $mem_size);
|
||||
$hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / ($cache['num_hits'] + $cache['num_misses']));
|
||||
$misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / ($cache['num_hits'] + $cache['num_misses']));
|
||||
$hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / $num_hits_and_misses);
|
||||
$misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / $num_hits_and_misses);
|
||||
|
||||
// Fragementation: (freeseg - 1) / total_seg
|
||||
// Fragmentation: (freeseg - 1) / total_seg
|
||||
$nseg = $freeseg = $fragsize = $freetotal = 0;
|
||||
for ($i = 0; $i < $mem['num_seg']; $i ++) {
|
||||
$ptr = 0;
|
||||
|
||||
@@ -38,13 +38,43 @@ if ($userinfo['change_serversettings'] == '1') {
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,7 +89,6 @@ if ($userinfo['change_serversettings'] == '1') {
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
|
||||
@@ -178,7 +178,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
|
||||
'hash' => $s
|
||||
));
|
||||
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
$insert = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
|
||||
`hash` = :hash,
|
||||
|
||||
@@ -290,9 +290,9 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
|
||||
// create serveralias options
|
||||
$serveraliasoptions = "";
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', '0', true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_www'], '1', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_none'], '2', Settings::Get('system.domaindefaultalias'), true, true);
|
||||
|
||||
$subcanemaildomain = \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['never'], '0', '0', true, true);
|
||||
$subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', '0', true, true);
|
||||
@@ -428,7 +428,7 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
$customer = Database::pexecute_first($customer_stmt, array(
|
||||
'customerid' => $result['customerid']
|
||||
));
|
||||
$result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')';
|
||||
$result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer);
|
||||
}
|
||||
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
@@ -594,6 +594,10 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
}
|
||||
|
||||
$result = \Froxlor\PhpHelper::htmlentitiesArray($result);
|
||||
if (Settings::Get('panel.allow_domain_change_customer') != '1') {
|
||||
$result['customername'] .= ' (<a href="' . $linker->getLink(array('section' => 'customers', 'page' => 'customers',
|
||||
'action' => 'su', 'id' => $customer['customerid'])) . '" rel="external">' . $customer['loginname'] . '</a>)';
|
||||
}
|
||||
|
||||
$domain_edit_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_edit.php';
|
||||
$domain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_edit_data);
|
||||
@@ -636,8 +640,8 @@ if ($page == 'domains' || $page == 'overview') {
|
||||
|
||||
// update customer/admin counters
|
||||
\Froxlor\User::updateCounters(false);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : '');
|
||||
\Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array(
|
||||
|
||||
@@ -32,10 +32,10 @@ if ($page == 'message') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message');
|
||||
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
if ($_POST['receipient'] == 0 && $userinfo['customers_see_all'] == '1') {
|
||||
if ($_POST['recipient'] == 0 && $userinfo['customers_see_all'] == '1') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to admins');
|
||||
$result = Database::query('SELECT `name`, `email` FROM `' . TABLE_PANEL_ADMINS . "`");
|
||||
} elseif ($_POST['receipient'] == 1) {
|
||||
} elseif ($_POST['recipient'] == 1) {
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers');
|
||||
$result = Database::query('SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "`");
|
||||
@@ -49,7 +49,7 @@ if ($page == 'message') {
|
||||
));
|
||||
}
|
||||
} else {
|
||||
\Froxlor\UI\Response::standard_error('noreceipientsgiven');
|
||||
\Froxlor\UI\Response::standard_error('norecipientsgiven');
|
||||
}
|
||||
|
||||
$subject = $_POST['subject'];
|
||||
@@ -105,7 +105,7 @@ if ($page == 'message') {
|
||||
$sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0;
|
||||
|
||||
if ($sentitems == 0) {
|
||||
$successmessage = $lng['message']['noreceipients'];
|
||||
$successmessage = $lng['message']['norecipients'];
|
||||
} else {
|
||||
$successmessage = str_replace('%s', $sentitems, $lng['message']['success']);
|
||||
}
|
||||
@@ -116,12 +116,12 @@ if ($page == 'message') {
|
||||
}
|
||||
|
||||
$action = '';
|
||||
$receipients = '';
|
||||
$recipients = '';
|
||||
|
||||
if ($userinfo['customers_see_all'] == '1') {
|
||||
$receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0);
|
||||
$recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['reseller'], 0);
|
||||
}
|
||||
|
||||
$receipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1);
|
||||
$recipients .= \Froxlor\UI\HTML::makeoption($lng['panel']['customer'], 1);
|
||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate('message/message') . "\";");
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ require './lib/init.php';
|
||||
|
||||
if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') {
|
||||
opcache_reset();
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reseted OPcache");
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "reset OPcache");
|
||||
header('Location: ' . $linker->getLink(array(
|
||||
'section' => 'opcacheinfo',
|
||||
'page' => 'showinfo'
|
||||
|
||||
@@ -66,11 +66,11 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
|
||||
'page' => $page
|
||||
), $_part, $settings_all, $settings_part, $only_enabledisable)) {
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles due to changed setting");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
|
||||
\Froxlor\UI\Response::standard_success('settingssaved', '', array(
|
||||
'filename' => $filename,
|
||||
@@ -146,12 +146,12 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
|
||||
if (isset($_POST['send']) && $_POST['send'] == 'send') {
|
||||
|
||||
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
|
||||
\Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array(
|
||||
'filename' => 'admin_index.php'
|
||||
|
||||
@@ -65,7 +65,7 @@ if ($page == 'overview') {
|
||||
eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";");
|
||||
|
||||
\Froxlor\User::updateCounters();
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
@chmod(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php', 0440);
|
||||
|
||||
$successful_update = true;
|
||||
|
||||
@@ -127,7 +127,7 @@ if ($action == 'delete') {
|
||||
|
||||
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys");
|
||||
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
|
||||
FROM `" . TABLE_API_KEYS . "` ak
|
||||
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`
|
||||
|
||||
23
build.xml
23
build.xml
@@ -6,21 +6,20 @@
|
||||
<property name="pdepend" value="${basedir}/vendor/bin/pdepend" />
|
||||
<property name="phpcpd" value="${basedir}/vendor/bin/phpcpd" />
|
||||
<property name="phpcs" value="${basedir}/vendor/bin/phpcs" />
|
||||
<property name="phpdox" value="${basedir}/vendor/bin/phpdox" />
|
||||
<property name="phploc" value="${basedir}/vendor/bin/phploc" />
|
||||
<property name="phpmd" value="${basedir}/vendor/bin/phpmd" />
|
||||
<property name="phpunit" value="${basedir}/vendor/bin/phpunit" />
|
||||
|
||||
<target name="full-build"
|
||||
depends="prepare,composer,static-analysis,phpunit,phpdox,-check-failure"
|
||||
depends="prepare,composer,static-analysis,phpunit,-check-failure"
|
||||
description="Performs static analysis, runs the tests, and generates project documentation" />
|
||||
|
||||
<target name="full-build-parallel"
|
||||
depends="prepare,composer,static-analysis-parallel,phpunit,phpdox,-check-failure"
|
||||
depends="prepare,composer,static-analysis-parallel,phpunit,-check-failure"
|
||||
description="Performs static analysis (executing the tools in parallel), runs the tests, and generates project documentation" />
|
||||
|
||||
<target name="quick-build"
|
||||
depends="prepare,composer,lint,phpunit-no-coverage"
|
||||
depends="prepare,composer,lint,phpunit-no-coverage,-check-failure"
|
||||
description="Performs a lint check and runs the tests (without generating code coverage reports)" />
|
||||
|
||||
<target name="static-analysis"
|
||||
@@ -49,7 +48,6 @@
|
||||
<delete dir="${basedir}/build/coverage" />
|
||||
<delete dir="${basedir}/build/logs" />
|
||||
<delete dir="${basedir}/build/pdepend" />
|
||||
<delete dir="${basedir}/build/phpdox" />
|
||||
<property name="clean.done" value="true" />
|
||||
</target>
|
||||
|
||||
@@ -59,7 +57,6 @@
|
||||
<mkdir dir="${basedir}/build/coverage" />
|
||||
<mkdir dir="${basedir}/build/logs" />
|
||||
<mkdir dir="${basedir}/build/pdepend" />
|
||||
<mkdir dir="${basedir}/build/phpdox" />
|
||||
|
||||
<property name="prepare.done" value="true" />
|
||||
</target>
|
||||
@@ -257,7 +254,7 @@
|
||||
<target name="phpunit-no-coverage" unless="phpunit.done"
|
||||
depends="composer"
|
||||
description="Run unit tests with PHPUnit (without generating code coverage reports)">
|
||||
<exec executable="${phpunit}" failonerror="true"
|
||||
<exec executable="${phpunit}" failonerror="true" resultproperty="result.phpunit"
|
||||
taskname="phpunit">
|
||||
<arg value="--configuration" />
|
||||
<arg path="${basedir}/phpunit.xml" />
|
||||
@@ -269,18 +266,6 @@
|
||||
<property name="phpunit.done" value="true" />
|
||||
</target>
|
||||
|
||||
<target name="phpdox" unless="phpdox.done"
|
||||
depends="phploc-ci,phpcs-ci,phpcompat-ci,phpmd-ci"
|
||||
description="Generate project documentation using phpDox">
|
||||
<exec executable="${phpdox}" dir="${basedir}/build"
|
||||
taskname="phpdox">
|
||||
<arg value="--file" />
|
||||
<arg path="${basedir}/phpdox.xml" />
|
||||
</exec>
|
||||
|
||||
<property name="phpdox.done" value="true" />
|
||||
</target>
|
||||
|
||||
<target name="-check-failure">
|
||||
<fail message="PHPUnit did not finish successfully">
|
||||
<condition>
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
"issues": "https://github.com/Froxlor/Froxlor/issues",
|
||||
"forum": "https://forum.froxlor.org/",
|
||||
"wiki": "https://github.com/Froxlor/Froxlor/wiki",
|
||||
"irc": "irc://chat.freenode.net/froxlor",
|
||||
"irc": "irc://irc.libera.chat/froxlor",
|
||||
"source": "https://github.com/Froxlor/Froxlor",
|
||||
"docs": "https://github.com/Froxlor/Froxlor/wiki"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1",
|
||||
"php": "^7.1 || ^8.0",
|
||||
"ext-session": "*",
|
||||
"ext-ctype": "*",
|
||||
"ext-pdo": "*",
|
||||
@@ -43,23 +43,23 @@
|
||||
"ext-curl": "*",
|
||||
"ext-json": "*",
|
||||
"ext-openssl": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"phpmailer/phpmailer": "~6.0",
|
||||
"monolog/monolog": "^1.24",
|
||||
"robthree/twofactorauth": "^1.6",
|
||||
"froxlor/idna-convert-legacy": "^2.1",
|
||||
"voku/anti-xss": "^4.1"
|
||||
},
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "8.4.1",
|
||||
"php": ">=7.3",
|
||||
"phpunit/phpunit": "^9",
|
||||
"ext-pcntl": "*",
|
||||
"phpcompatibility/php-compatibility": "*",
|
||||
"squizlabs/php_codesniffer": "*",
|
||||
"pdepend/pdepend": "^2.5",
|
||||
"sebastian/phpcpd": "^4.1",
|
||||
"theseer/phpdox": "^0.12.0",
|
||||
"phploc/phploc": "^5.0",
|
||||
"phpmd/phpmd": "^2.6"
|
||||
"pdepend/pdepend": "^2.9",
|
||||
"sebastian/phpcpd": "^6.0",
|
||||
"phploc/phploc": "^7.0",
|
||||
"phpmd/phpmd": "^2.10",
|
||||
"phpunit/php-timer" : "^5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "*",
|
||||
|
||||
2034
composer.lock
generated
2034
composer.lock
generated
File diff suppressed because it is too large
Load Diff
10
index.php
10
index.php
@@ -28,6 +28,12 @@ if ($action == '') {
|
||||
}
|
||||
|
||||
if (session_status() == PHP_SESSION_NONE) {
|
||||
ini_set("session.name", "s");
|
||||
ini_set("url_rewriter.tags", "");
|
||||
ini_set("session.use_cookies", false);
|
||||
ini_set("session.cookie_httponly", true);
|
||||
ini_set("session.cookie_secure", $is_ssl);
|
||||
session_id('login');
|
||||
session_start();
|
||||
}
|
||||
|
||||
@@ -372,6 +378,8 @@ if ($action == '2fa_entercode') {
|
||||
$lastscript = "";
|
||||
if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") {
|
||||
$lastscript = $_REQUEST['script'];
|
||||
$lastscript = str_replace("..", "", $lastscript);
|
||||
$lastscript = htmlspecialchars($lastscript, ENT_QUOTES);
|
||||
|
||||
if (! file_exists(__DIR__ . "/" . $lastscript)) {
|
||||
$lastscript = "";
|
||||
@@ -669,7 +677,7 @@ function finishLogin($userinfo)
|
||||
global $version, $dbversion, $remote_addr, $http_user_agent, $languages;
|
||||
|
||||
if (isset($userinfo['userid']) && $userinfo['userid'] != '') {
|
||||
$s = md5(uniqid(microtime(), 1));
|
||||
$s = \Froxlor\Froxlor::genSessionId();
|
||||
|
||||
if (isset($_POST['language'])) {
|
||||
$language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language');
|
||||
|
||||
@@ -495,7 +495,6 @@ opcache.load_comments
|
||||
opcache.revalidate_path
|
||||
opcache.save_comments
|
||||
opcache.use_cwd
|
||||
opcache.validate_timestamps
|
||||
opcache.fast_shutdown'),
|
||||
('phpfpm', 'ini_admin_values', 'cgi.redirect_status_env
|
||||
date.timezone
|
||||
@@ -519,7 +518,8 @@ opcache.restrict_api
|
||||
opcache.revalidate_freq
|
||||
opcache.max_accelerated_files
|
||||
opcache.memory_consumption
|
||||
opcache.interned_strings_buffer'),
|
||||
opcache.interned_strings_buffer
|
||||
opcache.validate_timestamps'),
|
||||
('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'),
|
||||
('system', 'lastaccountnumber', '0'),
|
||||
('system', 'lastguid', '9999'),
|
||||
@@ -532,7 +532,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'vmail_gid', '2000'),
|
||||
('system', 'vmail_homedir', '/var/customers/mail/'),
|
||||
('system', 'vmail_maildirname', 'Maildir'),
|
||||
('system', 'bind_enable', '1'),
|
||||
('system', 'bind_enable', '0'),
|
||||
('system', 'bindconf_directory', '/etc/bind/'),
|
||||
('system', 'bindreload_command', '/etc/init.d/bind9 reload'),
|
||||
('system', 'hostname', 'SERVERNAME'),
|
||||
@@ -611,6 +611,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'documentroot_use_default_value', '0'),
|
||||
('system', 'passwordcryptfunc', '3'),
|
||||
('system', 'axfrservers', ''),
|
||||
('system', 'powerdns_mode', 'Native'),
|
||||
('system', 'customer_ssl_path', '/etc/ssl/froxlor-custom/'),
|
||||
('system', 'allow_error_report_admin', '1'),
|
||||
('system', 'allow_error_report_customer', '0'),
|
||||
@@ -628,7 +629,7 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'apacheitksupport', '0'),
|
||||
('system', 'leprivatekey', 'unset'),
|
||||
('system', 'lepublickey', 'unset'),
|
||||
('system', 'letsencryptca', 'production'),
|
||||
('system', 'letsencryptca', 'letsencrypt'),
|
||||
('system', 'letsencryptcountrycode', 'DE'),
|
||||
('system', 'letsencryptstate', 'Hessen'),
|
||||
('system', 'letsencryptchallengepath', '/var/www/froxlor'),
|
||||
@@ -677,6 +678,11 @@ opcache.interned_strings_buffer'),
|
||||
('system', 'hide_incompatible_settings', '0'),
|
||||
('system', 'include_default_vhostconf', '0'),
|
||||
('system', 'soaemail', ''),
|
||||
('system', 'domaindefaultalias', '0'),
|
||||
('system', 'createstdsubdom_default', '1'),
|
||||
('system', 'froxlorusergroup', ''),
|
||||
('system', 'froxlorusergroup_gid', ''),
|
||||
('system', 'acmeshpath', '/root/.acme.sh/acme.sh'),
|
||||
('api', 'enabled', '0'),
|
||||
('2fa', 'enabled', '1'),
|
||||
('panel', 'decimal_places', '4'),
|
||||
@@ -689,7 +695,6 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'paging', '20'),
|
||||
('panel', 'natsorting', '1'),
|
||||
('panel', 'sendalternativemail', '0'),
|
||||
('panel', 'no_robots', '1'),
|
||||
('panel', 'allow_domain_change_admin', '0'),
|
||||
('panel', 'allow_domain_change_customer', '0'),
|
||||
('panel', 'frontend', 'froxlor'),
|
||||
@@ -714,8 +719,12 @@ opcache.interned_strings_buffer'),
|
||||
('panel', 'imprint_url', ''),
|
||||
('panel', 'terms_url', ''),
|
||||
('panel', 'privacy_url', ''),
|
||||
('panel', 'version', '0.10.26'),
|
||||
('panel', 'db_version', '202103240');
|
||||
('panel', 'logo_image_header', ''),
|
||||
('panel', 'logo_image_login', ''),
|
||||
('panel', 'logo_overridetheme', '0'),
|
||||
('panel', 'logo_overridecustom', '0'),
|
||||
('panel', 'version', '0.10.33'),
|
||||
('panel', 'db_version', '202112310');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_tasks`;
|
||||
@@ -814,7 +823,8 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES
|
||||
(4, 'Português', 'pt', 'lng/portugues.lng.php'),
|
||||
(5, 'Italiano', 'it', 'lng/italian.lng.php'),
|
||||
(6, 'Nederlands', 'nl', 'lng/dutch.lng.php'),
|
||||
(7, 'Svenska', 'sv', 'lng/swedish.lng.php');
|
||||
(7, 'Svenska', 'sv', 'lng/swedish.lng.php'),
|
||||
(8, 'Česká republika', 'cs', 'lng/czech.lng.php');
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `panel_syslog`;
|
||||
|
||||
@@ -123,7 +123,7 @@ class FroxlorInstall
|
||||
if ((isset($_POST['installstep']) && $_POST['installstep'] == '1') || (isset($_GET['check']) && $_GET['check'] == '1')) {
|
||||
$pagetitle = $this->_lng['install']['title'];
|
||||
if ($this->_checkPostData()) {
|
||||
// ceck data and create userdata etc.etc.etc.
|
||||
// check data and create userdata etc.etc.etc.
|
||||
$result = $this->_doInstall();
|
||||
} elseif (isset($_GET['check']) && $_GET['check'] == '1') {
|
||||
// gather data
|
||||
@@ -163,10 +163,13 @@ class FroxlorInstall
|
||||
|
||||
$this->_getPostField('mysql_host', '127.0.0.1');
|
||||
$this->_getPostField('mysql_database', 'froxlor');
|
||||
$this->_getPostField('mysql_forcecreate', '0');
|
||||
$this->_getPostField('mysql_unpriv_user', 'froxlor');
|
||||
$this->_getPostField('mysql_unpriv_pass');
|
||||
$this->_getPostField('mysql_root_user', 'root');
|
||||
$this->_getPostField('mysql_root_pass');
|
||||
$this->_getPostField('mysql_ssl_ca_file');
|
||||
$this->_getPostField('mysql_ssl_verify_server_certificate', 0);
|
||||
$this->_getPostField('admin_user', 'admin');
|
||||
$this->_getPostField('admin_pass1');
|
||||
$this->_getPostField('admin_pass2');
|
||||
@@ -212,6 +215,12 @@ class FroxlorInstall
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";";
|
||||
$fatal_fail = false;
|
||||
try {
|
||||
@@ -246,15 +255,23 @@ class FroxlorInstall
|
||||
$content .= $this->_status_message('green', "OK");
|
||||
// check for existing db and create backup if so
|
||||
$content .= $this->_backupExistingDatabase($db_root);
|
||||
// create unprivileged user and the database itself
|
||||
$content .= $this->_createDatabaseAndUser($db_root);
|
||||
// importing data to new database
|
||||
$content .= $this->_importDatabaseData();
|
||||
if (!$this->_abort) {
|
||||
// create unprivileged user and the database itself
|
||||
$content .= $this->_createDatabaseAndUser($db_root);
|
||||
// importing data to new database
|
||||
$content .= $this->_importDatabaseData();
|
||||
}
|
||||
if (! $this->_abort) {
|
||||
// create DB object for new database
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
|
||||
$another_fail = false;
|
||||
try {
|
||||
@@ -324,10 +341,14 @@ class FroxlorInstall
|
||||
$userdata .= "\$sql['user']='" . addcslashes($this->_data['mysql_unpriv_user'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['password']='" . addcslashes($this->_data['mysql_unpriv_pass'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['db']='" . addcslashes($this->_data['mysql_database'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['caption']='Default';\n";
|
||||
$userdata .= "\$sql_root[0]['host']='" . addcslashes($this->_data['mysql_host'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['user']='" . addcslashes($this->_data['mysql_root_user'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['password']='" . addcslashes($this->_data['mysql_root_pass'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['ssl']['caFile']='" . addcslashes($this->_data['mysql_ssl_ca_file'], "'\\") . "';\n";
|
||||
$userdata .= "\$sql_root[0]['ssl']['verifyServerCertificate']='" . addcslashes($this->_data['mysql_ssl_verify_server_certificate'], "'\\") . "';\n";
|
||||
$userdata .= "// enable debugging to browser in case of SQL errors\n";
|
||||
$userdata .= "\$sql['debug'] = false;\n";
|
||||
$userdata .= "?>";
|
||||
@@ -360,6 +381,30 @@ class FroxlorInstall
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate safe unique token
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
private function genUniqueToken(int $length = 16)
|
||||
{
|
||||
if(!isset($length) || intval($length) <= 8 ){
|
||||
$length = 16;
|
||||
}
|
||||
if (function_exists('random_bytes')) {
|
||||
return bin2hex(random_bytes($length));
|
||||
}
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
|
||||
}
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return bin2hex(openssl_random_pseudo_bytes($length));
|
||||
}
|
||||
// if everything else fails, use unsafe fallback
|
||||
return md5(uniqid(microtime(), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* create corresponding entries in froxlor database
|
||||
*
|
||||
@@ -403,8 +448,8 @@ class FroxlorInstall
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']);
|
||||
$ins_data = array(
|
||||
'loginname' => $this->_data['admin_user'],
|
||||
/* use SHA256 default crypt */
|
||||
'password' => crypt($this->_data['admin_pass1'], '$5$' . md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))),
|
||||
/* use SHA256 default crypt */
|
||||
'password' => crypt($this->_data['admin_pass1'], '$5$' . $this->genUniqueToken() . $this->genUniqueToken()),
|
||||
'email' => 'admin@' . $this->_data['servername'],
|
||||
'deflang' => $this->_languages[$this->_activelng]
|
||||
);
|
||||
@@ -555,6 +600,12 @@ class FroxlorInstall
|
||||
$options = array(
|
||||
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8'
|
||||
);
|
||||
|
||||
if (!empty($this->_data['mysql_ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $this->_data['mysql_ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $this->_data['mysql_ssl_verify_server_certificate'];
|
||||
}
|
||||
|
||||
$dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
|
||||
$fatal_fail = false;
|
||||
try {
|
||||
@@ -687,7 +738,7 @@ class FroxlorInstall
|
||||
if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
|
||||
// create user
|
||||
$stmt = $db_root->prepare("
|
||||
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED BY :password
|
||||
CREATE USER '" . $username . "'@'" . $access_host . "' IDENTIFIED WITH mysql_native_password BY :password
|
||||
");
|
||||
$stmt->execute(array(
|
||||
"password" => $password
|
||||
@@ -733,39 +784,59 @@ class FroxlorInstall
|
||||
));
|
||||
$rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn();
|
||||
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['check_db_exists']);
|
||||
|
||||
// check result
|
||||
if ($result_stmt !== false && $rows > 0) {
|
||||
$tables_exist = true;
|
||||
}
|
||||
|
||||
if ($tables_exist) {
|
||||
// tell whats going on
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']);
|
||||
if ((int)$this->_data['mysql_forcecreate'] > 0) {
|
||||
// set status
|
||||
$content .= $this->_status_message('orange', 'exists (' . $this->_data['mysql_database'] . ')');
|
||||
// tell what's going on
|
||||
$content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']);
|
||||
|
||||
// create temporary backup-filename
|
||||
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
|
||||
// create temporary backup-filename
|
||||
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
|
||||
|
||||
// look for mysqldump
|
||||
$do_backup = false;
|
||||
if (file_exists("/usr/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/bin/mysqldump';
|
||||
} elseif (file_exists("/usr/local/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/local/bin/mysqldump';
|
||||
}
|
||||
// look for mysqldump
|
||||
$do_backup = false;
|
||||
if (file_exists("/usr/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/bin/mysqldump';
|
||||
} elseif (file_exists("/usr/local/bin/mysqldump")) {
|
||||
$do_backup = true;
|
||||
$mysql_dump = '/usr/local/bin/mysqldump';
|
||||
}
|
||||
|
||||
if ($do_backup) {
|
||||
$command = $mysql_dump . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --password='" . escapeshellarg($this->_data['mysql_root_pass']) . "' --result-file=" . $filename;
|
||||
$output = exec($command);
|
||||
if (stristr($output, "error")) {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
|
||||
// create temporary .cnf file
|
||||
$cnffilename = "/tmp/froxlor_dump.cnf";
|
||||
$dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->_data['mysql_root_pass'] . "\"" . PHP_EOL;
|
||||
file_put_contents($cnffilename, $dumpcnf);
|
||||
|
||||
if ($do_backup) {
|
||||
$command = $mysql_dump . " --defaults-extra-file=" . $cnffilename . " " . escapeshellarg($this->_data['mysql_database']) . " -u " . escapeshellarg($this->_data['mysql_root_user']) . " --result-file=" . $filename;
|
||||
$output = [];
|
||||
exec($command, $output);
|
||||
@unlink($cnffilename);
|
||||
if (stristr(implode(" ", $output), "error") || ! file_exists($filename)) {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
|
||||
$this->_abort = true;
|
||||
} else {
|
||||
$content .= $this->_status_message('green', 'OK (' . $filename . ')');
|
||||
}
|
||||
} else {
|
||||
$content .= $this->_status_message('green', 'OK (' . $filename . ')');
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']);
|
||||
$this->_abort = true;
|
||||
}
|
||||
} else {
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']);
|
||||
$content .= $this->_status_message('red', $this->_lng['install']['db_exists']);
|
||||
$this->_abort = true;
|
||||
}
|
||||
} else {
|
||||
$content .= $content .= $this->_status_message('green', 'OK');
|
||||
}
|
||||
|
||||
return $content;
|
||||
@@ -784,7 +855,7 @@ class FroxlorInstall
|
||||
}
|
||||
// language selection
|
||||
$language_options = '';
|
||||
foreach ($this->_languages as $language_name => $language_file) {
|
||||
foreach ($this->_languages as $language_file => $language_name) {
|
||||
$language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true);
|
||||
}
|
||||
// get language-form-template
|
||||
@@ -801,6 +872,8 @@ class FroxlorInstall
|
||||
$formdata .= $this->_getSectionItemString('mysql_host', true);
|
||||
// database
|
||||
$formdata .= $this->_getSectionItemString('mysql_database', true);
|
||||
// database overwrite if exists?
|
||||
$formdata .= $this->_getSectionItemYesNo('mysql_forcecreate', false);
|
||||
// unpriv-user has to be different from root
|
||||
if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) {
|
||||
$style = 'blue';
|
||||
@@ -830,6 +903,9 @@ class FroxlorInstall
|
||||
}
|
||||
$formdata .= $this->_getSectionItemString('mysql_root_pass', true, $style, 'password');
|
||||
|
||||
$formdata .= $this->_getSectionItemString('mysql_ssl_ca_file', false, $style);
|
||||
$formdata .= $this->_getSectionItemYesNo('mysql_ssl_verify_server_certificate', false, $style);
|
||||
|
||||
/**
|
||||
* admin data
|
||||
*/
|
||||
@@ -867,19 +943,24 @@ class FroxlorInstall
|
||||
}
|
||||
|
||||
// show list of available distro's
|
||||
$distributions_select_data = [];
|
||||
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
|
||||
foreach ($distros as $_distribution) {
|
||||
$dist = new \Froxlor\Config\ConfigParser($_distribution);
|
||||
$dist_display = $dist->distributionName . " " . $dist->distributionCodename . " (" . $dist->distributionVersion . ")";
|
||||
if (!array_key_exists($dist_display, $distributions_select_data)) {
|
||||
$distributions_select_data[$dist_display] = '';
|
||||
}
|
||||
$distributions_select_data[$dist_display] .= str_replace(".xml", "", strtolower(basename($_distribution)));
|
||||
}
|
||||
|
||||
// sort by distribution name
|
||||
ksort($distributions_select_data);
|
||||
|
||||
$distributions_select = '';
|
||||
foreach ($distributions_select_data as $dist_display => $dist_index) {
|
||||
// create select-box-option
|
||||
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution']);
|
||||
$distributions_select .= \Froxlor\UI\HTML::makeoption($dist_display, $dist_index, $this->_data['distribution'] ?? '');
|
||||
// $this->_data['distribution']
|
||||
}
|
||||
|
||||
@@ -994,7 +1075,6 @@ class FroxlorInstall
|
||||
*/
|
||||
private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "")
|
||||
{
|
||||
$groupname = $this->_lng['install'][$groupname];
|
||||
$fieldlabel = $this->_lng['install'][$fieldname];
|
||||
|
||||
$sectionitem = "";
|
||||
@@ -1306,10 +1386,12 @@ class FroxlorInstall
|
||||
// from form
|
||||
if (! empty($_POST['serverip'])) {
|
||||
$this->_data['serverip'] = $_POST['serverip'];
|
||||
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
|
||||
return;
|
||||
// from $_SERVER
|
||||
} elseif (! empty($_SERVER['SERVER_ADDR'])) {
|
||||
$this->_data['serverip'] = $_SERVER['SERVER_ADDR'];
|
||||
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
|
||||
return;
|
||||
}
|
||||
// empty
|
||||
@@ -1357,7 +1439,14 @@ class FroxlorInstall
|
||||
|
||||
// read os-release
|
||||
if (file_exists('/etc/os-release')) {
|
||||
$os_dist = parse_ini_file('/etc/os-release', false);
|
||||
$os_dist_content = file_get_contents('/etc/os-release');
|
||||
$os_dist_arr = explode("\n", $os_dist_content);
|
||||
$os_dist = [];
|
||||
foreach ($os_dist_arr as $os_dist_line) {
|
||||
if (empty(trim($os_dist_line))) continue;
|
||||
$tmp = explode("=", $os_dist_line);
|
||||
$os_dist[$tmp[0]] = str_replace('"', "", trim($tmp[1]));
|
||||
}
|
||||
if (is_array($os_dist) && array_key_exists('ID', $os_dist) && array_key_exists('VERSION_ID', $os_dist)) {
|
||||
$os_version = explode('.', $os_dist['VERSION_ID'])[0];
|
||||
}
|
||||
|
||||
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no';
|
||||
$lng['requirements']['notfound'] = 'not found';
|
||||
$lng['requirements']['notinstalled'] = 'not installed';
|
||||
$lng['requirements']['activated'] = 'enabled';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.4 is preferred.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-extension...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-extension...';
|
||||
@@ -39,7 +39,7 @@ $lng['requirements']['phpjson'] = 'PHP json-extension...';
|
||||
$lng['requirements']['bcmathdescription'] = 'Traffic-calculation related functions will not work correctly!';
|
||||
$lng['requirements']['zipdescription'] = 'The auto-update feature requires the zip extension.';
|
||||
$lng['requirements']['openbasedir'] = 'open_basedir...';
|
||||
$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the coresponding php.ini';
|
||||
$lng['requirements']['openbasedirenabled'] = 'Froxlor will not work properly with open_basedir enabled. Please disable open_basedir for Froxlor in the corresponding php.ini';
|
||||
$lng['requirements']['mysqldump'] = 'MySQL dump tool';
|
||||
$lng['requirements']['mysqldumpmissing'] = 'Automatic backup of possible existing database is not possible. Please install mysql-client tools';
|
||||
$lng['requirements']['diedbecauseofrequirements'] = 'Cannot install Froxlor without these requirements! Try to fix them and retry.';
|
||||
@@ -53,10 +53,13 @@ $lng['install']['welcometext'] = 'Thank you for choosing Froxlor. Please fill ou
|
||||
$lng['install']['database'] = 'Database connection';
|
||||
$lng['install']['mysql_host'] = 'MySQL-Hostname';
|
||||
$lng['install']['mysql_database'] = 'Database name';
|
||||
$lng['install']['mysql_forcecreate'] = 'Backup and overwrite database if exists?';
|
||||
$lng['install']['mysql_unpriv_user'] = 'Username for the unprivileged MySQL-account';
|
||||
$lng['install']['mysql_unpriv_pass'] = 'Password for the unprivileged MySQL-account';
|
||||
$lng['install']['mysql_root_user'] = 'Username for the MySQL-root-account';
|
||||
$lng['install']['mysql_root_pass'] = 'Password for the MySQL-root-account';
|
||||
$lng['install']['mysql_ssl_ca_file'] = 'MySQL server certificate file path';
|
||||
$lng['install']['mysql_ssl_verify_server_certificate'] = 'Verify MySQL TLS certificate';
|
||||
$lng['install']['admin_account'] = 'Administrator Account';
|
||||
$lng['install']['admin_user'] = 'Administrator Username';
|
||||
$lng['install']['admin_pass1'] = 'Administrator Password';
|
||||
@@ -79,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'There seems to be a problem with the da
|
||||
$lng['install']['backup_old_db'] = 'Creating backup of old database...';
|
||||
$lng['install']['backup_binary_missing'] = 'Could not find mysqldump';
|
||||
$lng['install']['backup_failed'] = 'Could not backup database';
|
||||
$lng['install']['check_db_exists'] = 'Checking database...';
|
||||
$lng['install']['db_exists'] = 'Unable to create database. A database with the same name exists and should not be overwritten';
|
||||
$lng['install']['prepare_db'] = 'Preparing database...';
|
||||
$lng['install']['create_mysqluser_and_db'] = 'Creating database and username...';
|
||||
$lng['install']['testing_new_db'] = 'Testing if database and user have been created correctly...';
|
||||
|
||||
@@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non';
|
||||
$lng['requirements']['notfound'] = 'introuvable';
|
||||
$lng['requirements']['notinstalled'] = 'non installé';
|
||||
$lng['requirements']['activated'] = 'activé';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.0';
|
||||
$lng['requirements']['phpversion'] = 'PHP version >= 7.1';
|
||||
$lng['requirements']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...';
|
||||
$lng['requirements']['phpxml'] = 'extension PHP XML...';
|
||||
$lng['requirements']['phpfilter'] = 'extension PHP filter ...';
|
||||
|
||||
@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein';
|
||||
$lng['requirements']['notfound'] = 'nicht gefunden';
|
||||
$lng['requirements']['notinstalled'] = 'nicht installiert';
|
||||
$lng['requirements']['activated'] = 'ist aktiviert.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.0';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.';
|
||||
$lng['requirements']['phpversion'] = 'PHP Version >= 7.1';
|
||||
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.4 wird bevorzugt.';
|
||||
$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...';
|
||||
$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...';
|
||||
$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...';
|
||||
@@ -53,10 +53,13 @@ $lng['install']['welcometext'] = 'Vielen Dank dass Sie sich für Froxlor entschi
|
||||
$lng['install']['database'] = 'Datenbankverbindung';
|
||||
$lng['install']['mysql_host'] = 'MySQL-Hostname';
|
||||
$lng['install']['mysql_database'] = 'Datenbank Name';
|
||||
$lng['install']['mysql_forcecreate'] = 'Datenbank sichern und überschreiben wenn vorhanden?';
|
||||
$lng['install']['mysql_unpriv_user'] = 'Benutzername für den unprivilegierten MySQL-Account';
|
||||
$lng['install']['mysql_unpriv_pass'] = 'Passwort für den unprivilegierten MySQL-Account';
|
||||
$lng['install']['mysql_root_user'] = 'Benutzername für den MySQL-Root-Account';
|
||||
$lng['install']['mysql_root_pass'] = 'Passwort für den MySQL-Root-Account';
|
||||
$lng['install']['mysql_ssl_ca_file'] = 'MySQL-Server Zertifikatspfad';
|
||||
$lng['install']['mysql_ssl_verify_server_certificate'] = 'Validieren des MySQL-Server Zertifikats';
|
||||
$lng['install']['admin_account'] = 'Admin-Zugang';
|
||||
$lng['install']['admin_user'] = 'Administrator-Benutzername';
|
||||
$lng['install']['admin_pass1'] = 'Administrator-Passwort';
|
||||
@@ -79,6 +82,8 @@ $lng['install']['testing_mysql_fail'] = 'Bei der Verwendung der Datenbank gibt e
|
||||
$lng['install']['backup_old_db'] = 'Sicherung vorheriger Datenbank...';
|
||||
$lng['install']['backup_binary_missing'] = 'Konnte mysqldump nicht finden';
|
||||
$lng['install']['backup_failed'] = 'Sicherung fehlgeschlagen';
|
||||
$lng['install']['check_db_exists'] = 'Databenbank wird geprüft...';
|
||||
$lng['install']['db_exists'] = 'Datenbank kann nicht erstellt werden. Eine Datenbank mit dem selben Namen existiert bereits und soll nicht überschrieben werden.';
|
||||
$lng['install']['prepare_db'] = 'Datenbank wird vorbereitet...';
|
||||
$lng['install']['create_mysqluser_and_db'] = 'Erstelle Datenbank und Benutzer...';
|
||||
$lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt angelegt wurden...';
|
||||
|
||||
31
install/scripts/php-sessionclean.php
Executable file
31
install/scripts/php-sessionclean.php
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
|
||||
// Check if we're in the CLI
|
||||
if (@php_sapi_name() !== 'cli') {
|
||||
die('This script will only work in the shell.');
|
||||
}
|
||||
|
||||
require dirname(dirname(__DIR__)) . '/vendor/autoload.php';
|
||||
|
||||
// give control to command line handler
|
||||
try {
|
||||
\Froxlor\Cli\PhpSessioncleanCmd::processParameters($argc, $argv);
|
||||
} catch (Exception $e) {
|
||||
\Froxlor\Cli\PhpSessioncleanCmd::printerr($e->getMessage());
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Validate\Validate;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -803,3 +804,169 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.25')) {
|
||||
showUpdateStep("Updating from 0.10.25 to 0.10.26", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.26');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202103240')) {
|
||||
|
||||
showUpdateStep("Adding setting for default serveralias value for new domains", true);
|
||||
Settings::AddNew("system.domaindefaultalias", '0');
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202106160');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202106160')) {
|
||||
|
||||
showUpdateStep("Adjusting Let's Encrypt endpoint configuration to support ZeroSSL", true);
|
||||
if (Settings::Get('system.letsencryptca') == 'testing') {
|
||||
Settings::Set("system.letsencryptca", 'letsencrypt_test');
|
||||
} else {
|
||||
Settings::Set("system.letsencryptca", 'letsencrypt');
|
||||
}
|
||||
lastStepStatus(0);
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202106270');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202106270')) {
|
||||
showUpdateStep("Adding custom logo image settings", true);
|
||||
Settings::AddNew("panel.logo_image_header", '');
|
||||
Settings::AddNew("panel.logo_image_login", '');
|
||||
lastStepStatus(0);
|
||||
|
||||
// Migrating old custom logo over, if exists
|
||||
$custom_logo_file_old = \Froxlor\Froxlor::getInstallDir() . '/templates/Sparkle/assets/img/logo_custom.png';
|
||||
if (file_exists($custom_logo_file_old)) {
|
||||
showUpdateStep("Migrating existing custom logo to new settings", true);
|
||||
|
||||
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
|
||||
if (!is_dir($path) && !mkdir($path, 0775)) {
|
||||
throw new \Exception("img directory does not exist and cannot be created");
|
||||
}
|
||||
if (!is_writable($path)) {
|
||||
if (!chmod($path, 0775)) {
|
||||
throw new \Exception("Cannot write to img directory");
|
||||
}
|
||||
}
|
||||
|
||||
// Save as new custom logo header
|
||||
$save_to = 'logo_header.png';
|
||||
copy($custom_logo_file_old, $path.$save_to);
|
||||
Settings::Set("panel.logo_image_header", "img/{$save_to}?v=".time());
|
||||
|
||||
// Save as new custom logo login
|
||||
$save_to = 'logo_login.png';
|
||||
copy($custom_logo_file_old, $path.$save_to);
|
||||
Settings::Set("panel.logo_image_login", "img/{$save_to}?v=".time());
|
||||
|
||||
lastStepStatus(0);
|
||||
}
|
||||
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107070');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.26')) {
|
||||
showUpdateStep("Updating from 0.10.26 to 0.10.27", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.27');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107070')) {
|
||||
showUpdateStep("Adding settings to overwrite theme- or custom theme-logo with the new logo settings", true);
|
||||
Settings::AddNew("panel.logo_overridetheme", '0');
|
||||
Settings::AddNew("panel.logo_overridecustom", '0');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107200');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107200')) {
|
||||
showUpdateStep("Adding settings to define default value of 'create std-subdomain' when creating a customer", true);
|
||||
Settings::AddNew("system.createstdsubdom_default", '1');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107210');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107210')) {
|
||||
showUpdateStep("Normalizing ipv6 for correct comparison", true);
|
||||
$result_stmt = Database::prepare("
|
||||
SELECT `id`, `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "`"
|
||||
);
|
||||
Database::pexecute($result_stmt);
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_IPSANDPORTS . "` SET `ip` = :ip WHERE `id` = :id");
|
||||
while ($iprow = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
if (Validate::is_ipv6($iprow['ip'])) {
|
||||
$ip = inet_ntop(inet_pton($iprow['ip']));
|
||||
Database::pexecute($upd_stmt, [
|
||||
'ip' => $ip,
|
||||
'id' => $iprow['id']
|
||||
]);
|
||||
}
|
||||
}
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107260');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107260')) {
|
||||
showUpdateStep("Removing setting for search-engine allow yes/no", true);
|
||||
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'panel' AND `varname` = 'no_robots'");
|
||||
lastStepStatus(0);
|
||||
showUpdateStep("Adding setting to have all froxlor customers in a local group", true);
|
||||
Settings::AddNew("system.froxlorusergroup", '');
|
||||
Settings::AddNew("system.froxlorusergroup_gid", '');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202107300');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202107300')) {
|
||||
showUpdateStep("Adds the possibility to select the PowerDNS Operation Mode", true);
|
||||
Settings::AddNew("system.powerdns_mode", 'Native');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202108180');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.27')) {
|
||||
showUpdateStep("Updating from 0.10.27 to 0.10.28", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.28');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202108180')) {
|
||||
showUpdateStep("Adding czech language file", true);
|
||||
Database::query("INSERT INTO `" . TABLE_PANEL_LANGUAGE . "` SET `language` = 'Česká republika', `iso` = 'cs', `file` = 'lng/czech.lng.php'");
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202109040');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.28')) {
|
||||
showUpdateStep("Updating from 0.10.28 to 0.10.29", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.29');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29')) {
|
||||
showUpdateStep("Updating from 0.10.29 to 0.10.29.1", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.29.1');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.29.1')) {
|
||||
showUpdateStep("Updating from 0.10.29.1 to 0.10.30", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.30');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.30')) {
|
||||
showUpdateStep("Updating from 0.10.30 to 0.10.31", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.31');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('202109040')) {
|
||||
showUpdateStep("Add setting for acme.sh install location", true);
|
||||
Settings::AddNew("system.acmeshpath", '/root/.acme.sh/acme.sh');
|
||||
lastStepStatus(0);
|
||||
\Froxlor\Froxlor::updateToDbVersion('202112310');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.31')) {
|
||||
showUpdateStep("Updating from 0.10.31 to 0.10.32", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.32');
|
||||
}
|
||||
|
||||
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.32')) {
|
||||
showUpdateStep("Updating from 0.10.32 to 0.10.33", false);
|
||||
\Froxlor\Froxlor::updateToVersion('0.10.33');
|
||||
}
|
||||
|
||||
@@ -2505,7 +2505,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30')) {
|
||||
showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true);
|
||||
lastStepStatus(0);
|
||||
|
||||
showUpdateStep("Removing unsused tables");
|
||||
showUpdateStep("Removing unused tables");
|
||||
Database::query("DROP TABLE IF EXISTS `ipsandports_docrootsettings`;");
|
||||
Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;");
|
||||
lastStepStatus(0);
|
||||
@@ -2856,7 +2856,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc1')) {
|
||||
Settings::AddNew("system.croncmdline", $croncmdline);
|
||||
// add task to generate cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
// silenty add the auto-update setting - we do not want everybody to know and use this
|
||||
// silently add the auto-update setting - we do not want everybody to know and use this
|
||||
// as it is a very dangerous setting
|
||||
Settings::AddNew("system.cron_allowautoupdate", 0);
|
||||
lastStepStatus(0);
|
||||
@@ -3872,7 +3872,7 @@ opcache.interned_strings_buffer');
|
||||
|
||||
if (\Froxlor\Froxlor::isDatabaseVersion('201801110')) {
|
||||
|
||||
showUpdateStep("Adding php-fpm php PATH setting for envrironment");
|
||||
showUpdateStep("Adding php-fpm php PATH setting for environment");
|
||||
Settings::AddNew("phpfpm.envpath", '/usr/local/bin:/usr/bin:/bin');
|
||||
lastStepStatus(0);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Function getPreConfig
|
||||
*
|
||||
* outputs various content before the update process
|
||||
* can be continued (askes for agreement whatever is being asked)
|
||||
* can be continued (asks for agreement whatever is being asked)
|
||||
*
|
||||
* @param string $current_version
|
||||
* @param int $current_db_version
|
||||
|
||||
@@ -414,7 +414,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
|
||||
|
||||
if (Settings::Get('system.webserver') == 'apache2') {
|
||||
$has_preconfig = true;
|
||||
$description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in ordner to use it.<br />';
|
||||
$description = 'Froxlor now supports the new Apache 2.4. Please be aware that you need to load additional apache-modules in order to use it.<br />';
|
||||
$description .= '<pre>LoadModule authz_core_module modules/mod_authz_core.so
|
||||
LoadModule authz_host_module modules/mod_authz_host.so</pre><br />';
|
||||
$question = '<strong>Do you want to enable the Apache-2.4 modification?:</strong> ';
|
||||
|
||||
@@ -189,7 +189,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
*/
|
||||
public function listing()
|
||||
{
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$certs_stmt_query = "SELECT s.*, d.domain, d.letsencrypt, c.customerid, c.loginname
|
||||
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
|
||||
@@ -237,7 +237,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
*/
|
||||
public function listingCount()
|
||||
{
|
||||
// select all my (accessable) certificates
|
||||
// select all my (accessible) certificates
|
||||
$certs_stmt_query = "SELECT COUNT(*) as num_certs
|
||||
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
|
||||
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
|
||||
@@ -323,7 +323,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
));
|
||||
// trigger removing of certificate from acme.sh if let's encrypt
|
||||
if ($chk['letsencrypt'] == '1') {
|
||||
\Froxlor\System\Cronjob::inserttask('12', $chk['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $chk['domain']);
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] removed ssl-certificate for '" . $chk['domain'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
@@ -421,7 +421,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
// insert task to re-generate webserver-configs (#1260)
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
|
||||
), true, true);
|
||||
|
||||
// insert task to re-generate the cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] cronjob with description '" . $result['module'] . '/' . $result['cronfile'] . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('Cronjobs.get', array(
|
||||
'id' => $id
|
||||
|
||||
@@ -23,7 +23,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
|
||||
{
|
||||
|
||||
/**
|
||||
* check whether backup is enabled systemwide and if accessable for customer (hide_options)
|
||||
* check whether backup is enabled systemwide and if accessible for customer (hide_options)
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
@@ -108,7 +108,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
|
||||
'backup_web' => $backup_web
|
||||
);
|
||||
// schedule backup job
|
||||
\Froxlor\System\Cronjob::inserttask('20', $task_data);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_CUSTOMER_BACKUP, $task_data);
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] added customer-backup job for '" . $customer['loginname'] . "'. Target directory: " . $userpath);
|
||||
return $this->response(200, "successful", $task_data);
|
||||
|
||||
@@ -308,7 +308,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $mysqls_ul
|
||||
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
|
||||
* @param bool $createstdsubdomain
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false)
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default [system.createstdsubdom_default]
|
||||
* @param bool $phpenabled
|
||||
* optional, whether to allow usage of PHP, default 0 (false)
|
||||
* @param array $allowed_phpconfigs
|
||||
@@ -316,9 +316,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, wether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, wether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
* @param bool $store_defaultindex
|
||||
* optional, whether to store the default index file to customers homedir
|
||||
* @param int $hosting_plan_id
|
||||
@@ -352,7 +352,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$gender = (int) $this->getParam('gender', true, 0);
|
||||
$custom_notes = $this->getParam('custom_notes', true, '');
|
||||
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, Settings::Get('system.createstdsubdom_default'));
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
$sendpassword = $this->getBoolParam('sendpassword', true, 0);
|
||||
$store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0);
|
||||
@@ -645,10 +645,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
unset($ins_data);
|
||||
|
||||
// insert task to create homedir etc.
|
||||
\Froxlor\System\Cronjob::inserttask('2', $loginname, $guid, $guid, $store_defaultindex);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_HOME, $loginname, $guid, $guid, $store_defaultindex);
|
||||
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
// Add htpasswd for the stats-pages
|
||||
$htpasswdPassword = \Froxlor\System\Crypt::makeCryptPassword($password, true);
|
||||
@@ -674,7 +674,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added " . $stats_folder . " htpasswd for user '" . $loginname . "'");
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
// add default FTP-User
|
||||
// also, add froxlor-local user to ftp-group (if exists!) to
|
||||
@@ -739,7 +739,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'customerid' => $customerid
|
||||
), true, true);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $loginname . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -915,7 +915,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $mysqls_ul
|
||||
* optional, whether customer should have unlimited mysql-databases, default 0 (false)
|
||||
* @param bool $createstdsubdomain
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 0 (false)
|
||||
* optional, whether to create a standard-subdomain ([loginname].froxlor-hostname.tld), default 1 (if customer has std-subdomain) else 0 (false)
|
||||
* @param bool $phpenabled
|
||||
* optional, whether to allow usage of PHP, default 0 (false)
|
||||
* @param array $allowed_phpconfigs
|
||||
@@ -923,9 +923,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
* @param string $theme
|
||||
* optional, change theme
|
||||
*
|
||||
@@ -979,7 +979,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$email_pop3 = $this->getParam('email_pop3', true, $result['pop3']);
|
||||
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
|
||||
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, 0);
|
||||
$createstdsubdomain = $this->getBoolParam('createstdsubdomain', true, ($result['standardsubdomain'] != 0 ? 1 : 0));
|
||||
$password = $this->getParam('new_customer_password', true, '');
|
||||
$phpenabled = $this->getBoolParam('phpenabled', true, $result['phpenabled']);
|
||||
$allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true));
|
||||
@@ -1051,7 +1051,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($createstdsubdomain != '1') {
|
||||
if ($createstdsubdomain != '1' || $deactivated) {
|
||||
$createstdsubdomain = '0';
|
||||
}
|
||||
|
||||
@@ -1088,7 +1088,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'customerid' => $result['customerid']
|
||||
), true, true);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1102,11 +1102,11 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_ERR, "[API] Unable to delete standard-subdomain: " . $e->getMessage());
|
||||
}
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically deleted standardsubdomain for user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
if ($phpenabled != $result['phpenabled'] || $perlenabled != $result['perlenabled'] || $email != $result['email']) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
// activate/deactivate customer services
|
||||
@@ -1192,7 +1192,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
), true, true);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] " . ($deactivated ? 'deactivated' : 'reactivated') . " user '" . $result['loginname'] . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
// Disable or enable POP3 Login for customers Mail Accounts
|
||||
@@ -1304,7 +1304,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
$admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` ";
|
||||
|
||||
@@ -1512,9 +1512,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
'did' => $row['id']
|
||||
), true, true);
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $row['domain']);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $row['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $row['domain']);
|
||||
}
|
||||
// remove customer domains
|
||||
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
|
||||
@@ -1643,18 +1643,18 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
|
||||
}
|
||||
|
||||
// rebuild configs
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
if ($delete_userfiles == 1) {
|
||||
// insert task to remove the customers files from the filesystem
|
||||
\Froxlor\System\Cronjob::inserttask('6', $result['loginname']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_CUSTOMER_FILES, $result['loginname']);
|
||||
}
|
||||
|
||||
// Using filesystem - quota, insert a task which cleans the filesystem - quota
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
|
||||
@@ -123,7 +123,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added directory-option for '" . $userpath . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
$result = $this->apiCall('DirOptions.get', array(
|
||||
'id' => $id
|
||||
@@ -248,7 +248,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
if (($options_indexes != $result['options_indexes']) || ($error404path != $result['error404path']) || ($error403path != $result['error403path']) || ($error500path != $result['error500path']) || ($options_cgi != $result['options_cgi'])) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_HTACCESS . "`
|
||||
SET `options_indexes` = :options_indexes,
|
||||
@@ -322,7 +322,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable directory options
|
||||
* returns the total number of accessible directory options
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
@@ -413,7 +413,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
"id" => $id
|
||||
), true, true);
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted directory-option for '" . str_replace($customer_data['documentroot'], '/', $result['path']) . "'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$id = Database::lastInsertId();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added directory-protection for '" . $username . " (" . $path . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
|
||||
$result = $this->apiCall('DirProtections.get', array(
|
||||
'id' => $id
|
||||
@@ -251,7 +251,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid
|
||||
");
|
||||
Database::pexecute($upd_stmt, $upd_params, true, true);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] updated directory-protection '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
@@ -305,7 +305,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable directory protections
|
||||
* returns the total number of accessible directory protections
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select directory-protections of a specific customer by id
|
||||
@@ -385,7 +385,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
|
||||
));
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted htpasswd for '" . $result['username'] . " (" . $result['path'] . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,7 +336,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$dom_entries[] = $new_entry;
|
||||
|
||||
// re-generate bind configs
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$result = $this->apiCall('DomainZones.get', array(
|
||||
'id' => $id
|
||||
@@ -542,7 +542,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
), true, true);
|
||||
if ($del_stmt->rowCount() > 0) {
|
||||
// re-generate bind configs
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
return $this->response(200, "successful", true);
|
||||
}
|
||||
return $this->response(304, "successful", true);
|
||||
|
||||
@@ -77,7 +77,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable domains
|
||||
* returns the total number of accessible domains
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -193,6 +193,27 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
return $ipandports;
|
||||
}
|
||||
|
||||
/**
|
||||
* get ips from array of id's
|
||||
*
|
||||
* @param array $ips
|
||||
* @return array
|
||||
*/
|
||||
private function getIpsFromIdArray(array $ids)
|
||||
{
|
||||
$resultips_stmt = Database::prepare("
|
||||
SELECT `ip` FROM `" . TABLE_PANEL_IPSANDPORTS . "` WHERE id = :id
|
||||
");
|
||||
$result = [];
|
||||
foreach ($ids as $id) {
|
||||
$entry = Database::pexecute_first($resultips_stmt, array(
|
||||
'id' => $id
|
||||
));
|
||||
$result[] = $entry['ip'];
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* add new domain entry
|
||||
*
|
||||
@@ -213,12 +234,12 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* @param bool $email_only
|
||||
* optional, restrict domain to email usage, default 0 (false)
|
||||
* @param int $selectserveralias
|
||||
* optional, 0 = wildcard, 1 = www-alias, 2 = none, default 0
|
||||
* optional, 0 = wildcard, 1 = www-alias, 2 = none, default [system.domaindefaultalias]
|
||||
* @param bool $speciallogfile
|
||||
* optional, whether to create an exclusive web-logfile for this domain, default 0 (false)
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none)
|
||||
* @param bool $issubof
|
||||
* @param int $issubof
|
||||
* optional, domain-id of a domain this domain is a subdomain of (required for webserver-cronjob to generate the correct order), default 0 (none)
|
||||
* @param string $registration_date
|
||||
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
|
||||
@@ -309,7 +330,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$subcanemaildomain = $this->getParam('subcanemaildomain', true, 0);
|
||||
$isemaildomain = $this->getBoolParam('isemaildomain', true, 0);
|
||||
$email_only = $this->getBoolParam('email_only', true, 0);
|
||||
$serveraliasoption = $this->getParam('selectserveralias', true, 0);
|
||||
$serveraliasoption = $this->getParam('selectserveralias', true, Settings::Get('system.domaindefaultalias'));
|
||||
$speciallogfile = $this->getBoolParam('speciallogfile', true, 0);
|
||||
$aliasdomain = intval($this->getParam('alias', true, 0));
|
||||
$issubof = $this->getParam('issubof', true, 0);
|
||||
@@ -406,6 +427,20 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . $path_suffix);
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
} elseif (substr($documentroot, 0, 1) == '/' && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$registration_date = \Froxlor\Validate\Validate::validate($registration_date, 'registration_date', '/^(19|20)\d\d[-](0[1-9]|1[012])[-](0[1-9]|[12][0-9]|3[01])$/', '', array(
|
||||
'0000-00-00',
|
||||
'0',
|
||||
@@ -433,17 +468,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
\Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (! empty($documentroot)) {
|
||||
if (substr($documentroot, 0, 1) != '/' && ! preg_match('/^https?\:\/\//', $documentroot)) {
|
||||
$documentroot = $_documentroot . '/' . $documentroot;
|
||||
}
|
||||
} else {
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
$ssl_protocols = array();
|
||||
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||
@@ -486,7 +510,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = '0';
|
||||
$writeaccesslog = '1';
|
||||
$writeerrorlog = '1';
|
||||
$documentroot = $_documentroot;
|
||||
$override_tls = '0';
|
||||
$ssl_protocols = array();
|
||||
}
|
||||
@@ -574,6 +597,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$include_specialsettings = 0;
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($domain);
|
||||
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
|
||||
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($serveraliasoption == '0' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
@@ -825,9 +857,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
|
||||
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger());
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] added domain '" . $domain . "'");
|
||||
|
||||
@@ -871,7 +903,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
* optional, when setting $speciallogfile to false, this needs to be set to true to confirm the action, default 0 (false)
|
||||
* @param int $alias
|
||||
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none)
|
||||
* @param bool $issubof
|
||||
* @param int $issubof
|
||||
* optional, domain-id of a domain this domain is a subdomain of (required for webserver-cronjob to generate the correct order), default 0 (none)
|
||||
* @param string $registration_date
|
||||
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
|
||||
@@ -1157,6 +1189,38 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$serveraliasoption = $p_serveraliasoption;
|
||||
}
|
||||
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
if (! empty($documentroot) && $documentroot != $result['documentroot'] && substr($documentroot, 0, 1) == '/' && substr($documentroot, 0, strlen($customer['documentroot'])) != $customer['documentroot'] && $this->getUserDetail('change_serversettings') != '1') {
|
||||
\Froxlor\UI\Response::standard_error('pathmustberelative', '', true);
|
||||
}
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
|
||||
if ($this->getUserDetail('change_serversettings') == '1') {
|
||||
|
||||
if (Settings::Get('system.bind_enable') == '1') {
|
||||
@@ -1171,33 +1235,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
|
||||
$documentroot = \Froxlor\Validate\Validate::validate($documentroot, 'documentroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
|
||||
// when moving customer and no path is specified, update would normally reuse the current document-root
|
||||
// which would point to the wrong customer, therefore we will re-create that directory
|
||||
if (! empty($documentroot) && $customerid > 0 && $customerid != $result['customerid'] && Settings::Get('panel.allow_domain_change_customer') == '1') {
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$_documentroot = $customer['documentroot'];
|
||||
}
|
||||
// set the customers default docroot
|
||||
$documentroot = $_documentroot;
|
||||
}
|
||||
|
||||
if ($documentroot == '') {
|
||||
// If path is empty and 'Use domain name as default value for DocumentRoot path' is enabled in settings,
|
||||
// set default path to subdomain or domain name
|
||||
if (Settings::Get('system.documentroot_use_default_value') == 1) {
|
||||
$documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $result['domain']);
|
||||
} else {
|
||||
$documentroot = $customer['documentroot'];
|
||||
}
|
||||
}
|
||||
|
||||
if (! preg_match('/^https?\:\/\//', $documentroot) && strstr($documentroot, ":") !== false) {
|
||||
\Froxlor\UI\Response::standard_error('pathmaynotcontaincolon', '', true);
|
||||
}
|
||||
|
||||
$ssl_protocols = array();
|
||||
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
|
||||
@@ -1237,7 +1274,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$notryfiles = $result['notryfiles'];
|
||||
$writeaccesslog = $result['writeaccesslog'];
|
||||
$writeerrorlog = $result['writeerrorlog'];
|
||||
$documentroot = $result['documentroot'];
|
||||
$ssl_protocols = $p_ssl_protocols;
|
||||
$override_tls = $result['override_tls'];
|
||||
}
|
||||
@@ -1326,6 +1362,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$include_specialsettings = 0;
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($result['domain']);
|
||||
$selected_ips = $this->getIpsFromIdArray($ssl_ipandports);
|
||||
if ($domain_ips == false || count(array_intersect($selected_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($serveraliasoption == '0' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
@@ -1419,8 +1464,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
|
||||
$iswildcarddomain = ($serveraliasoption == '0') ? '1' : '0';
|
||||
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
if ($documentroot != $result['documentroot'] || $ssl_redirect != $result['ssl_redirect'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $phpenabled != $result['phpenabled'] || $openbasedir != $result['openbasedir'] || $phpsettingid != $result['phpsettingid'] || $mod_fcgid_starter != $result['mod_fcgid_starter'] || $mod_fcgid_maxrequests != $result['mod_fcgid_maxrequests'] || $specialsettings != $result['specialsettings'] || $ssl_specialsettings != $result['ssl_specialsettings'] || $notryfiles != $result['notryfiles'] || $writeaccesslog != $result['writeaccesslog'] || $writeerrorlog != $result['writeerrorlog'] || $aliasdomain != $result['aliasdomain'] || $issubof != $result['ismainbutsubto'] || $email_only != $result['email_only'] || ($speciallogfile != $result['speciallogfile'] && $speciallogverified == '1') || $letsencrypt != $result['letsencrypt'] || $http2 != $result['http2'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $ocsp_stapling != $result['ocsp_stapling']) {
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
}
|
||||
|
||||
if ($speciallogfile != $result['speciallogfile'] && $speciallogverified != '1') {
|
||||
@@ -1428,11 +1473,11 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
}
|
||||
|
||||
if ($isbinddomain != $result['isbinddomain'] || $zonefile != $result['zonefile'] || $dkim != $result['dkim'] || $isemaildomain != $result['isemaildomain']) {
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
}
|
||||
// check whether nameserver has been disabled, #581
|
||||
if ($isbinddomain != $result['isbinddomain'] && $isbinddomain == 0) {
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
}
|
||||
|
||||
if ($isemaildomain == '0' && $result['isemaildomain'] == '1') {
|
||||
@@ -1461,7 +1506,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
'id' => $id
|
||||
), true, true);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
}
|
||||
|
||||
$updatechildren = '';
|
||||
@@ -1702,9 +1747,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
");
|
||||
Database::pexecute($_update_stmt, $_update_data, true, true);
|
||||
|
||||
// insert a rebuild-task
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
|
||||
// Cleanup domain <-> ip mapping
|
||||
$del_stmt = Database::prepare("
|
||||
DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id
|
||||
@@ -1942,16 +1984,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
|
||||
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
|
||||
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] deleted domain/subdomains (#" . $result['id'] . ")");
|
||||
\Froxlor\User::updateCounters();
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
|
||||
@@ -499,7 +499,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
|
||||
}
|
||||
|
||||
if ($delete_userfiles) {
|
||||
\Froxlor\System\Cronjob::inserttask('7', $customer['loginname'], $result['email_full']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_EMAIL_DATA, $customer['loginname'], $result['email_full']);
|
||||
}
|
||||
|
||||
// decrease usage for customer
|
||||
|
||||
@@ -326,7 +326,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable email addresses
|
||||
* returns the total number of accessible email addresses
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select email addresses of a specific customer by id
|
||||
|
||||
@@ -79,7 +79,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable fpm daemons
|
||||
* returns the total number of accessible fpm daemons
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -178,9 +178,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$custom_config = $this->getParam('custom_config', true, '');
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$reload_cmd = \Froxlor\Validate\Validate::validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
@@ -229,7 +229,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$id = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
@@ -299,9 +299,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$custom_config = $this->getParam('custom_config', true, $result['custom_config']);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$reload_cmd = \Froxlor\Validate\Validate::validate($reload_cmd, 'reload_cmd', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', '', '', array(), true);
|
||||
$config_dir = \Froxlor\Validate\Validate::validate($config_dir, 'config_dir', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
|
||||
if (! in_array($pmanager, array(
|
||||
'static',
|
||||
'dynamic',
|
||||
@@ -351,7 +351,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
$result = $this->apiCall('FpmDaemons.get', array(
|
||||
'id' => $id
|
||||
@@ -400,7 +400,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] fpm-daemon setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
|
||||
@@ -123,12 +123,12 @@ class Froxlor extends \Froxlor\Api\ApiCommand
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " imported settings");
|
||||
try {
|
||||
\Froxlor\SImExporter::import($json_str);
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// cron.d file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
return $this->response(200, "successful", true);
|
||||
} catch (\Exception $e) {
|
||||
throw new \Exception($e->getMessage(), 406);
|
||||
|
||||
@@ -62,7 +62,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
if (($this->getUserDetail('ftps_used') < $this->getUserDetail('ftps') || $this->getUserDetail('ftps') == '-1') || $this->isAdmin() && $is_defaultuser == 1) {
|
||||
|
||||
// required paramters
|
||||
// required parameters
|
||||
$path = $this->getParam('path');
|
||||
$password = $this->getParam('ftp_password');
|
||||
|
||||
@@ -79,7 +79,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
|
||||
@@ -234,7 +234,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added ftp-account '" . $username . " (" . $path . ")'");
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
|
||||
if ($sendinfomail == 1) {
|
||||
$replace_arr = array(
|
||||
@@ -396,7 +396,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(trim($description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if (Settings::Get('system.allow_customer_shell') == '1') {
|
||||
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
|
||||
@@ -450,7 +450,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
// it's the task for "new ftp" but that will
|
||||
// create all directories and correct their permissions
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_FTP_USERS . "`
|
||||
@@ -512,7 +512,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable ftp accounts
|
||||
* returns the total number of accessible ftp accounts
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select ftp-users of a specific customer by id
|
||||
@@ -628,11 +628,11 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
|
||||
|
||||
// refs #293
|
||||
if ($delete_userfiles == 1) {
|
||||
\Froxlor\System\Cronjob::inserttask('8', $customer_data['loginname'], $result['homedir']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_FTP_DATA, $customer_data['loginname'], $result['homedir']);
|
||||
} else {
|
||||
if (Settings::Get('system.nssextrausers') == 1) {
|
||||
// this is used so that the libnss-extrausers cron is fired
|
||||
\Froxlor\System\Cronjob::inserttask(5);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable hosting plans
|
||||
* returns the total number of accessible hosting plans
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -182,9 +182,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, whether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, whether to allow access to webserver access/error-logs, default 0 (false)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -216,7 +216,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$value_arr['email_quota'] = - 1;
|
||||
@@ -309,9 +309,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
* @param bool $perlenabled
|
||||
* optional, whether to allow usage of Perl/CGI, default 0 (false)
|
||||
* @param bool $dnsenabled
|
||||
* optional, ether to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* optional, either to allow usage of the DNS editor (requires activated nameserver in settings), default 0 (false)
|
||||
* @param bool $logviewenabled
|
||||
* optional, ether to allow acccess to webserver access/error-logs, default 0 (false)
|
||||
* optional, either to allow access to webserver access/error-logs, default 0 (false)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -361,7 +361,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
|
||||
|
||||
// validation
|
||||
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', '/^[^\0]*$/');
|
||||
$description = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $description), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT);
|
||||
|
||||
if (Settings::Get('system.mail_quota_enabled') != '1') {
|
||||
$value_arr['email_quota'] = - 1;
|
||||
|
||||
@@ -65,7 +65,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable ip/port entries
|
||||
* returns the total number of accessible ip/port entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -247,6 +247,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($ip));
|
||||
|
||||
$result_checkfordouble_stmt = Database::prepare("
|
||||
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
|
||||
WHERE `ip` = :ip AND `port` = :port");
|
||||
@@ -295,9 +298,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
Database::pexecute($ins_stmt, $ins_data);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
|
||||
$ip = '[' . $ip . ']';
|
||||
@@ -462,6 +465,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$docroot = '';
|
||||
}
|
||||
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($ip));
|
||||
|
||||
if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport == false) {
|
||||
\Froxlor\UI\Response::standard_error('cantchangesystemip', '', true);
|
||||
} elseif ($result_checkfordouble && $result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
|
||||
@@ -505,9 +511,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] changed IP/port from '" . $result['ip'] . ":" . $result['port'] . "' to '" . $ip . ":" . $port . "'");
|
||||
|
||||
@@ -578,9 +584,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Api\Commands;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
@@ -31,6 +32,8 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
* optional, default is 0
|
||||
* @param string $description
|
||||
* optional, description for database
|
||||
* @param string $custom_suffix
|
||||
* optional, name for database
|
||||
* @param bool $sendinfomail
|
||||
* optional, send created resource-information to customer, default: false
|
||||
* @param int $customerid
|
||||
@@ -44,132 +47,144 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
// required paramters
|
||||
$password = $this->getParam('mysql_password');
|
||||
if (($this->getUserDetail('mysqls_used') < $this->getUserDetail('mysqls') || $this->getUserDetail('mysqls') == '-1') || $this->isAdmin()) {
|
||||
// required parameters
|
||||
$password = $this->getParam('mysql_password');
|
||||
|
||||
// parameters
|
||||
$dbserver = $this->getParam('mysql_server', true, 0);
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData('mysqls');
|
||||
// parameters
|
||||
$dbserver = $this->getParam('mysql_server', true, 0);
|
||||
$databasedescription = $this->getParam('description', true, '');
|
||||
$databasename = $this->getParam('custom_suffix', true, '');
|
||||
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
|
||||
// get needed customer info to reduce the mysql-usage-counter by one
|
||||
$customer = $this->getCustomerData('mysqls');
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
|
||||
// validate whether the dbserver exists
|
||||
$dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
if (! isset($sql_root) || ! is_array($sql_root)) {
|
||||
throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404);
|
||||
}
|
||||
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
|
||||
$newdb_params = array(
|
||||
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
|
||||
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
|
||||
);
|
||||
// create database, user, set permissions, etc.pp.
|
||||
$dbm = new \Froxlor\Database\DbManager($this->logger());
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
|
||||
|
||||
// we've checked against the password in dbm->createDatabase
|
||||
if ($username == false) {
|
||||
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
// add database info to froxlor
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
|
||||
SET
|
||||
`customerid` = :customerid,
|
||||
`databasename` = :databasename,
|
||||
`description` = :description,
|
||||
`dbserver` = :dbserver
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"databasename" => $username,
|
||||
"description" => $databasedescription,
|
||||
"dbserver" => $dbserver
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$databaseid = Database::lastInsertId();
|
||||
$params['id'] = $databaseid;
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'mysqls_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
|
||||
|
||||
// send info-mail?
|
||||
if ($sendinfomail == 1) {
|
||||
$pma = $this->lng['admin']['notgiven'];
|
||||
if (Settings::Get('panel.phpmyadmin_url') != '') {
|
||||
$pma = Settings::Get('panel.phpmyadmin_url');
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$password = \Froxlor\System\Crypt::validatePassword($password, true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
if (!empty($databasename)) {
|
||||
$databasename = \Froxlor\Validate\Validate::validate(trim($databasename), 'database_name', '/^[A-Za-z0-9][A-Za-z0-9\-_]+$/i', '', array(), true);
|
||||
}
|
||||
|
||||
// validate whether the dbserver exists
|
||||
$dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
$userinfo = $customer;
|
||||
if (!isset($sql_root) || !is_array($sql_root)) {
|
||||
throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404);
|
||||
}
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($userinfo),
|
||||
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($userinfo), // < keep this for compatibility
|
||||
'NAME' => $userinfo['name'],
|
||||
'FIRSTNAME' => $userinfo['firstname'],
|
||||
'COMPANY' => $userinfo['company'],
|
||||
'CUSTOMER_NO' => $userinfo['customernumber'],
|
||||
'DB_NAME' => $username,
|
||||
'DB_PASS' => htmlentities(htmlentities($password)),
|
||||
'DB_DESC' => $databasedescription,
|
||||
'DB_SRV' => $sql_root['host'],
|
||||
'PMA_URI' => $pma
|
||||
if ($sendinfomail != 1) {
|
||||
$sendinfomail = 0;
|
||||
}
|
||||
|
||||
$newdb_params = array(
|
||||
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
|
||||
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
|
||||
);
|
||||
// create database, user, set permissions, etc.pp.
|
||||
$dbm = new \Froxlor\Database\DbManager($this->logger());
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo));
|
||||
$this->mailer()->send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
if (strtoupper(Settings::Get('customer.mysqlprefix')) == 'DBNAME' && !empty($databasename)) {
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'] . '_' . $databasename, $password);
|
||||
} else {
|
||||
$username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
\Froxlor\UI\Response::standard_error('errorsendingmail', $userinfo['email'], true);
|
||||
// we've checked against the password in dbm->createDatabase
|
||||
if ($username == false) {
|
||||
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
// add database info to froxlor
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DATABASES . "`
|
||||
SET
|
||||
`customerid` = :customerid,
|
||||
`databasename` = :databasename,
|
||||
`description` = :description,
|
||||
`dbserver` = :dbserver
|
||||
");
|
||||
$params = array(
|
||||
"customerid" => $customer['customerid'],
|
||||
"databasename" => $username,
|
||||
"description" => $databasedescription,
|
||||
"dbserver" => $dbserver
|
||||
);
|
||||
Database::pexecute($stmt, $params, true, true);
|
||||
$databaseid = Database::lastInsertId();
|
||||
$params['id'] = $databaseid;
|
||||
|
||||
// update customer usage
|
||||
Customers::increaseUsage($customer['customerid'], 'mysqls_used');
|
||||
Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
|
||||
|
||||
// send info-mail?
|
||||
if ($sendinfomail == 1) {
|
||||
$pma = $this->lng['admin']['notgiven'];
|
||||
if (Settings::Get('panel.phpmyadmin_url') != '') {
|
||||
$pma = Settings::Get('panel.phpmyadmin_url');
|
||||
}
|
||||
|
||||
Database::needRoot(true, $dbserver);
|
||||
Database::needSqlData();
|
||||
$sql_root = Database::getSqlData();
|
||||
Database::needRoot(false);
|
||||
$userinfo = $customer;
|
||||
|
||||
$replace_arr = array(
|
||||
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($userinfo),
|
||||
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($userinfo), // < keep this for compatibility
|
||||
'NAME' => $userinfo['name'],
|
||||
'FIRSTNAME' => $userinfo['firstname'],
|
||||
'COMPANY' => $userinfo['company'],
|
||||
'CUSTOMER_NO' => $userinfo['customernumber'],
|
||||
'DB_NAME' => $username,
|
||||
'DB_PASS' => htmlentities(htmlentities($password)),
|
||||
'DB_DESC' => $databasedescription,
|
||||
'DB_SRV' => $sql_root['host'],
|
||||
'PMA_URI' => $pma
|
||||
);
|
||||
|
||||
// get template for mail subject
|
||||
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']);
|
||||
// get template for mail body
|
||||
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
|
||||
|
||||
$_mailerror = false;
|
||||
$mailerr_msg = "";
|
||||
try {
|
||||
$this->mailer()->Subject = $mail_subject;
|
||||
$this->mailer()->AltBody = $mail_body;
|
||||
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body));
|
||||
$this->mailer()->addAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo));
|
||||
$this->mailer()->send();
|
||||
} catch (\PHPMailer\PHPMailer\Exception $e) {
|
||||
$mailerr_msg = $e->errorMessage();
|
||||
$_mailerror = true;
|
||||
} catch (\Exception $e) {
|
||||
$mailerr_msg = $e->getMessage();
|
||||
$_mailerror = true;
|
||||
}
|
||||
|
||||
if ($_mailerror) {
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg);
|
||||
\Froxlor\UI\Response::standard_error('errorsendingmail', $userinfo['email'], true);
|
||||
}
|
||||
|
||||
$this->mailer()->clearAddresses();
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'");
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $username
|
||||
));
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'");
|
||||
|
||||
$result = $this->apiCall('Mysqls.get', array(
|
||||
'dbname' => $username
|
||||
));
|
||||
return $this->response(200, "successful", $result);
|
||||
throw new \Exception("No more resources available", 406);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,7 +206,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
|
||||
if ($this->isAdmin()) {
|
||||
if ($this->getUserDetail('customers_see_all') != 1) {
|
||||
@@ -291,7 +306,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
@@ -305,13 +320,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
));
|
||||
$id = $result['id'];
|
||||
|
||||
// paramters
|
||||
// parameters
|
||||
$password = $this->getParam('mysql_password', true, '');
|
||||
$databasedescription = $this->getParam('description', true, $result['description']);
|
||||
|
||||
// validation
|
||||
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', '', '', array(), true);
|
||||
$databasedescription = \Froxlor\Validate\Validate::validate(trim($databasedescription), 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
|
||||
if ($password != '') {
|
||||
// validate password
|
||||
@@ -378,7 +393,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
public function listing()
|
||||
{
|
||||
$result = array();
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer_ids = $this->getAllowedCustomerIds('mysql');
|
||||
$query_fields = array();
|
||||
$result_stmt = Database::prepare("
|
||||
@@ -428,7 +443,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable databases
|
||||
* returns the total number of accessible databases
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select dbs of a specific customer by id
|
||||
@@ -475,7 +490,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
|
||||
$id = $this->getParam('id', true, 0);
|
||||
$dn_optional = ($id <= 0 ? false : true);
|
||||
$dbname = $this->getParam('dbname', $dn_optional, '');
|
||||
$dbserver = $this->getParam('mysql_server', true, - 1);
|
||||
$dbserver = $this->getParam('mysql_server', true, -1);
|
||||
$customer = $this->getCustomerData();
|
||||
|
||||
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
|
||||
|
||||
@@ -122,7 +122,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable php-setting entries
|
||||
* returns the total number of accessible php-setting entries
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -217,6 +217,8 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
* @param bool $allow_all_customers
|
||||
* optional add this configuration to the list of every existing customer's allowed-fpm-config list, default is false (no)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -261,9 +263,10 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$max_requests = $this->getParam('max_requests', true, $def_fpmconfig['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $def_fpmconfig['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $def_fpmconfig['limit_extensions']);
|
||||
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
|
||||
@@ -361,12 +364,14 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
Database::pexecute($ins_stmt, $ins_data, true, true);
|
||||
$ins_data['id'] = Database::lastInsertId();
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been created by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $ins_data['id']
|
||||
));
|
||||
|
||||
$this->addForAllCustomers($allow_all_customers, $ins_data['id']);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
@@ -418,6 +423,8 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
* optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
|
||||
* @param string $limit_extensions
|
||||
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value
|
||||
* @param bool $allow_all_customers
|
||||
* optional add this configuration to the list of every existing customer's allowed-fpm-config list, default is false (no)
|
||||
*
|
||||
* @access admin
|
||||
* @throws \Exception
|
||||
@@ -456,9 +463,10 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
$max_requests = $this->getParam('max_requests', true, $result['max_requests']);
|
||||
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
|
||||
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
|
||||
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
|
||||
|
||||
// validation
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', '', '', array(), true);
|
||||
$description = \Froxlor\Validate\Validate::validate($description, 'description', \Froxlor\Validate\Validate::REGEX_DESC_TEXT, '', array(), true);
|
||||
$phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
|
||||
if (Settings::Get('system.mod_fcgid') == 1) {
|
||||
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
|
||||
@@ -557,12 +565,14 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
);
|
||||
Database::pexecute($upd_stmt, $upd_data, true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting with description '" . $description . "' has been updated by '" . $this->getUserDetail('loginname') . "'");
|
||||
|
||||
$result = $this->apiCall('PhpSettings.get', array(
|
||||
'id' => $id
|
||||
));
|
||||
|
||||
$this->addForAllCustomers($allow_all_customers, $id);
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
@@ -612,10 +622,44 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
|
||||
'id' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] php setting '" . $result['description'] . "' has been deleted by '" . $this->getUserDetail('loginname') . "'");
|
||||
return $this->response(200, "successful", $result);
|
||||
}
|
||||
throw new \Exception("Not allowed to execute given command.", 403);
|
||||
}
|
||||
|
||||
/**
|
||||
* add given php-config id to the list of allowed php-config to all currently existing customers
|
||||
* if allow_all_customers parameter is true in PhpSettings::add() or PhpSettings::update()
|
||||
*
|
||||
* @param bool $allow_all_customers
|
||||
* @param int $config_id
|
||||
*/
|
||||
private function addForAllCustomers(bool $allow_all_customers, int $config_id)
|
||||
{
|
||||
// should this config be added to the allowed list of all existing customers?
|
||||
if ($allow_all_customers) {
|
||||
$sel_stmt = Database::prepare("SELECT customerid, allowed_phpconfigs FROM `" . TABLE_PANEL_CUSTOMERS . "`");
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET allowed_phpconfigs = :ap WHERE customerid = :cid");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($cust = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
// get existing entries of customer
|
||||
$ap = json_decode($cust['allowed_phpconfigs'], true);
|
||||
// initialize array if it's empty
|
||||
if (empty($ap)) {
|
||||
$ap = [];
|
||||
}
|
||||
// add this config
|
||||
$ap[] = $config_id;
|
||||
// check for duplicates and force value-type to be int
|
||||
$ap = array_map('intval', array_unique($ap));
|
||||
// update customer-entry
|
||||
Database::pexecute($upd_stmt, [
|
||||
'ap' => json_encode($ap),
|
||||
'cid' => $cust['customerid']
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Froxlor\Api\Commands;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Domain\Domain;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
@@ -230,6 +231,15 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$our_ips = Domain::getIpsOfDomain($domain_check['id']);
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($completedomain);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
if ($ssl_redirect > 0 && $letsencrypt == 1) {
|
||||
$ssl_redirect = 2;
|
||||
@@ -252,6 +262,19 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$phpsid_result['phpsettingid'] = intval($phpsettingid);
|
||||
}
|
||||
|
||||
$allowed_phpconfigs = $customer['allowed_phpconfigs'];
|
||||
if (! empty($allowed_phpconfigs)) {
|
||||
$allowed_phpconfigs = json_decode($allowed_phpconfigs, true);
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsid_result['phpsettingid'], $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// actually insert domain
|
||||
$stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
@@ -336,9 +359,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
\Froxlor\Domain\Domain::addRedirectToDomain($subdomain_id, $redirectcode);
|
||||
}
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
|
||||
Customers::increaseUsage($customer['customerid'], 'subdomains_used');
|
||||
|
||||
@@ -595,9 +618,18 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
}
|
||||
|
||||
// validate dns if lets encrypt is enabled to check whether we can use it at all
|
||||
if ($result['letsencrypt'] != $letsencrypt && $letsencrypt == '1' && Settings::Get('system.le_domain_dnscheck') == '1') {
|
||||
$our_ips = Domain::getIpsOfDomain($result['parentdomainid']);
|
||||
$domain_ips = \Froxlor\PhpHelper::gethostbynamel6($result['domain']);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
\Froxlor\UI\Response::standard_error('invaliddnsforletsencrypt', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// We can't enable let's encrypt for wildcard-domains
|
||||
if ($iswildcarddomain == '1' && $letsencrypt == '1') {
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt');
|
||||
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
|
||||
}
|
||||
|
||||
// Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
|
||||
@@ -619,12 +651,25 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] automatically deleted mail-table entries for '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
|
||||
$allowed_phpconfigs = $customer['allowed_phpconfigs'];
|
||||
if (! empty($allowed_phpconfigs)) {
|
||||
$allowed_phpconfigs = json_decode($allowed_phpconfigs, true);
|
||||
} else {
|
||||
$allowed_phpconfigs = [];
|
||||
}
|
||||
// only with fcgid/fpm enabled will it be possible to select a php-setting
|
||||
if ((int) Settings::Get('system.mod_fcgid') == 1 || (int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (! in_array($phpsettingid, $allowed_phpconfigs)) {
|
||||
\Froxlor\UI\Response::standard_error('notallowedphpconfigused', '', true);
|
||||
}
|
||||
}
|
||||
|
||||
// handle redirect
|
||||
if ($_doredirect) {
|
||||
\Froxlor\Domain\Domain::updateRedirectOfDomain($id, $redirectcode);
|
||||
}
|
||||
|
||||
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != $result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
|
||||
if ($path != $result['documentroot'] || $isemaildomain != $result['isemaildomain'] || $wwwserveralias != $result['wwwserveralias'] || $iswildcarddomain != $result['iswildcarddomain'] || $aliasdomain != (int)$result['aliasdomain'] || $openbasedir_path != $result['openbasedir_path'] || $ssl_redirect != $result['ssl_redirect'] || $letsencrypt != $result['letsencrypt'] || $hsts_maxage != $result['hsts'] || $hsts_sub != $result['hsts_sub'] || $hsts_preload != $result['hsts_preload'] || $phpsettingid != $result['phpsettingid']) {
|
||||
$stmt = Database::prepare("
|
||||
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
|
||||
`documentroot` = :documentroot,
|
||||
@@ -688,11 +733,11 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'id' => $id
|
||||
), true, true);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
}
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
|
||||
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] edited domain '" . $idna_convert->decode($result['domain']) . "'");
|
||||
}
|
||||
@@ -810,7 +855,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the total number of accessable subdomain entries
|
||||
* returns the total number of accessible subdomain entries
|
||||
*
|
||||
* @param int $customerid
|
||||
* optional, admin-only, select (sub)domains of a specific customer by id
|
||||
@@ -974,13 +1019,13 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
|
||||
'domainid' => $id
|
||||
), true, true);
|
||||
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// Using nameserver, insert a task which rebuilds the server config
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// remove domains DNS from powerDNS if used, #581
|
||||
\Froxlor\System\Cronjob::inserttask('11', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_PDNS, $result['domain']);
|
||||
// remove domain from acme.sh / lets encrypt if used
|
||||
\Froxlor\System\Cronjob::inserttask('12', $result['domain']);
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
|
||||
|
||||
// reduce subdomain-usage-counter
|
||||
Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
|
||||
|
||||
@@ -133,7 +133,7 @@ abstract class BulkAction
|
||||
|
||||
$new_data = array();
|
||||
foreach ($this->api_params as $idx => $param) {
|
||||
if (isset($data_array[$idx]) && ! empty($data_array[$idx])) {
|
||||
if (isset($data_array[$idx])) {
|
||||
$new_data[$param] = $data_array[$idx];
|
||||
}
|
||||
}
|
||||
@@ -150,7 +150,7 @@ abstract class BulkAction
|
||||
|
||||
/**
|
||||
* reads in the csv import file and returns an array with
|
||||
* all the entites to be imported
|
||||
* all the entities to be imported
|
||||
*
|
||||
* @param string $separator
|
||||
*
|
||||
|
||||
@@ -85,8 +85,8 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
$distributions_select_data = array();
|
||||
|
||||
//set default os.
|
||||
$os_dist = array('ID' => 'buster');
|
||||
$os_version = array('0' => '10');
|
||||
$os_dist = array('ID' => 'bullseye');
|
||||
$os_version = array('0' => '11');
|
||||
$os_default = $os_dist['ID'];
|
||||
|
||||
//read os-release
|
||||
@@ -341,13 +341,43 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
|
||||
// try to convert namserver hosts to ip's
|
||||
$ns_ips = "";
|
||||
$known_ns_ips = [];
|
||||
if (Settings::Get('system.nameservers') != '') {
|
||||
$nameservers = explode(',', Settings::Get('system.nameservers'));
|
||||
foreach ($nameservers as $nameserver) {
|
||||
$nameserver = trim($nameserver);
|
||||
// DNS servers might be multi homed; allow transfer from all ip
|
||||
// addresses of the DNS server
|
||||
$nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
|
||||
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) {
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
// append dot to hostname
|
||||
if (substr($nameserver, - 1, 1) != '.') {
|
||||
$nameserver .= '.';
|
||||
}
|
||||
// ignore invalid responses
|
||||
if (! is_array($nameserver_ips)) {
|
||||
// act like \Froxlor\PhpHelper::gethostbynamel6() and return unmodified hostname on error
|
||||
$nameserver_ips = array(
|
||||
$nameserver
|
||||
);
|
||||
} else {
|
||||
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
|
||||
}
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= implode(",", $nameserver_ips);
|
||||
}
|
||||
}
|
||||
|
||||
// AXFR server
|
||||
if (Settings::Get('system.axfrservers') != '') {
|
||||
$axfrservers = explode(',', Settings::Get('system.axfrservers'));
|
||||
foreach ($axfrservers as $axfrserver) {
|
||||
if (!in_array(trim($axfrserver), $known_ns_ips)) {
|
||||
if (!empty($ns_ips)) {
|
||||
$ns_ips .= ',';
|
||||
}
|
||||
$ns_ips .= trim($axfrserver);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -365,7 +395,6 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
'<SERVERIP>' => Settings::Get('system.ipaddress'),
|
||||
'<NAMESERVERS>' => Settings::Get('system.nameservers'),
|
||||
'<NAMESERVERS_IP>' => $ns_ips,
|
||||
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
|
||||
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
|
||||
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
|
||||
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
|
||||
@@ -402,7 +431,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
100
lib/Froxlor/Cli/Action/PhpSessioncleanAction.php
Normal file
100
lib/Froxlor/Cli/Action/PhpSessioncleanAction.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli\Action;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Cli\PhpSessioncleanCmd;
|
||||
|
||||
class PhpSessioncleanAction extends \Froxlor\Cli\Action
|
||||
{
|
||||
|
||||
public function __construct($args)
|
||||
{
|
||||
parent::__construct($args);
|
||||
}
|
||||
|
||||
public function run()
|
||||
{
|
||||
$this->validate();
|
||||
|
||||
if ((int) Settings::Get('phpfpm.enabled') == 1) {
|
||||
if (isset($this->_args["max-lifetime"]) && is_numeric($this->_args["max-lifetime"]) && $this->_args["max-lifetime"] > 0) {
|
||||
$this->cleanSessionfiles((int)$this->_args["max-lifetime"]);
|
||||
} else {
|
||||
// use default max-lifetime value
|
||||
$this->cleanSessionfiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* validates the parsed command line parameters
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function validate()
|
||||
{
|
||||
global $lng;
|
||||
|
||||
$this->checkConfigParam(true);
|
||||
$this->parseConfig();
|
||||
|
||||
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
|
||||
}
|
||||
|
||||
private function cleanSessionfiles(int $maxlifetime = 1440)
|
||||
{
|
||||
// store paths to clean up
|
||||
$paths_to_clean = [];
|
||||
// get all pool-config directories configured
|
||||
$sel_stmt = Database::prepare("SELECT DISTINCT `config_dir` FROM `" . TABLE_PANEL_FPMDAEMONS . "`");
|
||||
Database::pexecute($sel_stmt);
|
||||
while ($fpmd = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
|
||||
$poolfiles = glob(\Froxlor\FileDir::makeCorrectFile($fpmd['config_dir'] . '/*.conf'));
|
||||
foreach ($poolfiles as $cf) {
|
||||
$contents = file_get_contents($cf);
|
||||
$pattern = preg_quote('session.save_path', '/');
|
||||
$pattern = "/" . $pattern . ".+?\=(.*)/";
|
||||
if (preg_match_all($pattern, $contents, $matches)) {
|
||||
$paths_to_clean[] = \Froxlor\FileDir::makeCorrectDir(trim($matches[1][0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// every path is just needed once
|
||||
$paths_to_clean = array_unique($paths_to_clean);
|
||||
|
||||
if (count($paths_to_clean) > 0) {
|
||||
foreach ($paths_to_clean as $ptc) {
|
||||
// find all files older then maxlifetime and delete them
|
||||
\Froxlor\FileDir::safe_exec("find -O3 \"" . $ptc . "\" -ignore_readdir_race -depth -mindepth 1 -name 'sess_*' -type f -cmin \"+" . $maxlifetime . "\" -delete");
|
||||
}
|
||||
}
|
||||
}
|
||||
private function parseConfig()
|
||||
{
|
||||
define('FROXLOR_INSTALL_DIR', $this->_args['froxlor-dir']);
|
||||
if (!class_exists('\\Froxlor\\Database\\Database')) {
|
||||
throw new \Exception("Could not find froxlor's Database class. Is froxlor really installed to '" . FROXLOR_INSTALL_DIR . "'?");
|
||||
}
|
||||
if (!file_exists(FROXLOR_INSTALL_DIR . '/lib/userdata.inc.php')) {
|
||||
throw new \Exception("Could not find froxlor's userdata.inc.php file. You should use this script only with a fully installed and setup froxlor system.");
|
||||
}
|
||||
}
|
||||
|
||||
private function checkConfigParam($needed = false)
|
||||
{
|
||||
if ($needed) {
|
||||
if (!isset($this->_args["froxlor-dir"])) {
|
||||
$this->_args["froxlor-dir"] = \Froxlor\Froxlor::getInstallDir();
|
||||
} elseif (!is_dir($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given --froxlor-dir parameter is not a directory");
|
||||
} elseif (!file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (!is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class SwitchServerIpAction extends \Froxlor\Cli\Action
|
||||
$ip_list = $this->_args['switch'];
|
||||
|
||||
if (empty($ip_list) || is_bool($ip_list)) {
|
||||
throw new \Exception("No paramters given for --switch action.");
|
||||
throw new \Exception("No parameters given for --switch action.");
|
||||
}
|
||||
|
||||
$ips_to_switch = array();
|
||||
@@ -179,7 +179,7 @@ class SwitchServerIpAction extends \Froxlor\Cli\Action
|
||||
} elseif (! file_exists($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
|
||||
} elseif (! is_readable($this->_args["froxlor-dir"])) {
|
||||
throw new \Exception("Given froxlor direcotry cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
throw new \Exception("Given froxlor directory cannot be read ('" . $this->_args["froxlor-dir"] . "')");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
64
lib/Froxlor/Cli/PhpSessioncleanCmd.php
Normal file
64
lib/Froxlor/Cli/PhpSessioncleanCmd.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cli;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2022 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Froxlor team <team@froxlor.org> (2018-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Cron
|
||||
*
|
||||
*/
|
||||
class PhpSessioncleanCmd extends CmdLineHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* list of valid switches
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $switches = array(
|
||||
'h'
|
||||
);
|
||||
|
||||
/**
|
||||
* list of valid parameters
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $params = array(
|
||||
'froxlor-dir',
|
||||
'max-lifetime',
|
||||
'help'
|
||||
);
|
||||
|
||||
public static $action_class = '\\Froxlor\\Cli\\Action\\PhpSessioncleanAction';
|
||||
|
||||
public static function printHelp()
|
||||
{
|
||||
self::println("");
|
||||
self::println("Help / command line parameters:");
|
||||
self::println("");
|
||||
// commands
|
||||
self::println("--froxlor-dir\t\tpath to froxlor installation");
|
||||
self::println("\t\t\tExample: --froxlor-dir=/var/www/froxlor/");
|
||||
self::println("");
|
||||
self::println("--max-lifetime\t\tThe number of seconds after which data will be seen as 'garbage' and potentially cleaned up. Defaults to '1440'");
|
||||
self::println("\t\t\tExample: --max-lifetime=2000");
|
||||
self::println("");
|
||||
self::println("--help\t\t\tshow help screen (this)");
|
||||
self::println("");
|
||||
// switches
|
||||
self::println("-h\t\t\tsame as --help");
|
||||
self::println("");
|
||||
|
||||
die(); // end of execution
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ class ConfigDaemon
|
||||
private $isparsed = false;
|
||||
|
||||
/**
|
||||
* Sub - area of the full - XML only holding the daemon - data we are interessted in
|
||||
* Sub - area of the full - XML only holding the daemon - data we are interested in
|
||||
*
|
||||
* @var \SimpleXMLElement
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace Froxlor\Cron\Dns;
|
||||
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2016 the Froxlor Team (see authors).
|
||||
@@ -97,26 +99,29 @@ class PowerDNS extends DnsBase
|
||||
));
|
||||
$pdns_domain = $pdns_domains_stmt->fetch(\PDO::FETCH_ASSOC);
|
||||
|
||||
$del_rec_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_meta_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_dom_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
if ($pdns_domain && ! empty($pdns_domain['id'])) {
|
||||
$del_rec_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_meta_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
$del_dom_stmt->execute(array(
|
||||
'did' => $pdns_domain['id']
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function insertZone($domainname, $serial = 0)
|
||||
{
|
||||
$ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare("
|
||||
INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = 'NATIVE'
|
||||
INSERT INTO domains set `name` = :domainname, `notified_serial` = :serial, `type` = :type
|
||||
");
|
||||
$ins_stmt->execute(array(
|
||||
'domainname' => $domainname,
|
||||
'serial' => $serial
|
||||
'serial' => $serial,
|
||||
'type' => strtoupper(Settings::Get('system.powerdns_mode'))
|
||||
));
|
||||
$lastid = \Froxlor\Dns\PowerDNS::getDB()->lastInsertId();
|
||||
return $lastid;
|
||||
|
||||
@@ -826,7 +826,7 @@ class Apache extends HttpConfigBase
|
||||
// After inserting the AWStats information,
|
||||
// be sure to build the awstats conf file as well
|
||||
// and chown it using $awstats_params, #258
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the informations
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the information
|
||||
\Froxlor\Http\Statistics::createAWStatsConf(Settings::Get('system.logfiles_directory') . $domain['loginname'] . $speciallogfile . '-access.log', $domain['domain'], $alias . $server_alias, $domain['customerroot'], $domain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,9 @@ class ApacheFcgi extends Apache
|
||||
// start block, cut off last pipe and close block
|
||||
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')';
|
||||
$php_options_text .= ' <FilesMatch \.' . $filesmatch . '$>' . "\n";
|
||||
$php_options_text .= ' SetHandler proxy:unix:' . $domain['fpm_socket'] . '|fcgi://localhost' . "\n";
|
||||
$php_options_text .= ' <If "-f %{SCRIPT_FILENAME}">' . "\n";
|
||||
$php_options_text .= ' SetHandler proxy:unix:' . $domain['fpm_socket'] . '|fcgi://localhost' . "\n";
|
||||
$php_options_text .= ' </If>' . "\n";
|
||||
$php_options_text .= ' </FilesMatch>' . "\n";
|
||||
|
||||
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
|
||||
|
||||
@@ -287,7 +287,7 @@ class ConfigIO
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a file/direcotry from the settings and checks whether it exists
|
||||
* returns a file/directory from the settings and checks whether it exists
|
||||
*
|
||||
* @param string $group
|
||||
* settings-group
|
||||
|
||||
@@ -28,6 +28,14 @@ use Froxlor\FileDir;
|
||||
class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
|
||||
const ACME_PROVIDER = [
|
||||
'letsencrypt' => "https://acme-v02.api.letsencrypt.org/directory",
|
||||
'letsencrypt_test' => "https://acme-staging-v02.api.letsencrypt.org/directory",
|
||||
'buypass' => "https://api.buypass.com/acme/directory",
|
||||
'buypass_test' => "https://api.test4.buypass.no/acme/directory",
|
||||
'zerossl' => "https://acme.zerossl.com/v2/DV90"
|
||||
];
|
||||
|
||||
private static $apiserver = "";
|
||||
|
||||
private static $acmesh = "/root/.acme.sh/acme.sh";
|
||||
@@ -63,7 +71,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
$issue_domains = self::issueDomains();
|
||||
$renew_froxlor = self::renewFroxlorVhost();
|
||||
$renew_domains = self::renewDomains(true);
|
||||
if ($issue_froxlor || !empty($issue_domains) || !empty($renew_froxlor) || $renew_domains) {
|
||||
if ($issue_froxlor || ! empty($issue_domains) || ! empty($renew_froxlor) || $renew_domains) {
|
||||
// insert task to generate certificates and vhost-configs
|
||||
\Froxlor\System\Cronjob::inserttask(1);
|
||||
}
|
||||
@@ -71,7 +79,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
|
||||
// set server according to settings
|
||||
self::$apiserver = 'https://acme-' . (Settings::Get('system.letsencryptca') == 'testing' ? 'staging-' : '') . 'v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org/directory';
|
||||
self::$apiserver = self::ACME_PROVIDER[Settings::Get('system.letsencryptca')];
|
||||
|
||||
// validate acme.sh installation
|
||||
if (! self::checkInstall()) {
|
||||
@@ -123,7 +131,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
'ssl_key_file' => null,
|
||||
'ssl_ca_file' => null,
|
||||
'ssl_csr_file' => null,
|
||||
'id' => null
|
||||
'id' => null,
|
||||
'wwwserveralias' => 0
|
||||
);
|
||||
|
||||
// add to queue
|
||||
@@ -157,7 +166,8 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
'ssl_key_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_key_file'] : null,
|
||||
'ssl_ca_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_ca_file'] : null,
|
||||
'ssl_csr_file' => is_array($renew_froxlor) ? $renew_froxlor['ssl_csr_file'] : null,
|
||||
'id' => is_array($renew_froxlor) ? $renew_froxlor['id'] : null
|
||||
'id' => is_array($renew_froxlor) ? $renew_froxlor['id'] : null,
|
||||
'wwwserveralias' => 0
|
||||
);
|
||||
$renew_domains[] = $certrow;
|
||||
}
|
||||
@@ -279,12 +289,18 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
$our_ips = Domain::getIpsOfDomain($domain_id);
|
||||
foreach ($loop_domains as $idx => $domain) {
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Validating DNS of " . $domain);
|
||||
// ips accordint to NS
|
||||
// ips according to NS
|
||||
$domain_ips = PhpHelper::gethostbynamel6($domain);
|
||||
if ($domain_ips == false || count(array_intersect($our_ips, $domain_ips)) <= 0) {
|
||||
// no common ips...
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Skipping Let's Encrypt generation for " . $domain . " due to no system known IP address via DNS check");
|
||||
unset($domains[$idx]);
|
||||
// in order to avoid a cron-loop that tries to get a certificate every 5 minutes, we disable let's encrypt for this domain
|
||||
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `letsencrypt` = '0' WHERE `id` = :did");
|
||||
Database::pexecute($upd_stmt, [
|
||||
'did' => $domain_id
|
||||
]);
|
||||
$cronlog->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Let's Encrypt deactivated for domain " . $domain);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,7 +310,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
{
|
||||
if (! empty($domains)) {
|
||||
|
||||
$acmesh_cmd = self::$acmesh . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
$acmesh_cmd = self::getAcmeSh() . " --server " . self::$apiserver . " --issue -d " . implode(" -d ", $domains);
|
||||
// challenge path
|
||||
$acmesh_cmd .= " -w " . Settings::Get('system.letsencryptchallengepath');
|
||||
if (Settings::Get('system.leecc') > 0) {
|
||||
@@ -306,7 +322,7 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
if (Settings::Get('system.letsencryptreuseold') != '1') {
|
||||
$acmesh_cmd .= " --always-force-new-domain-key";
|
||||
}
|
||||
if (Settings::Get('system.letsencryptca') == 'testing') {
|
||||
if (Settings::Get('system.letsencryptca') == 'letsencrypt_test') {
|
||||
$acmesh_cmd .= " --staging";
|
||||
}
|
||||
if ($force) {
|
||||
@@ -514,10 +530,10 @@ class AcmeSh extends \Froxlor\Cron\FroxlorCron
|
||||
if (Settings::Get('system.leecc') > 0 && ! $forced_noecc) {
|
||||
$domain .= "_ecc";
|
||||
}
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::$acmesh) . '/acme.sh.env');
|
||||
$env_file = FileDir::makeCorrectFile(dirname(self::getAcmeSh()) . '/acme.sh.env');
|
||||
if (file_exists($env_file)) {
|
||||
$output = [];
|
||||
$cut = <<<EOC
|
||||
$cut = <<<EOC
|
||||
cut -d'"' -f2
|
||||
EOC;
|
||||
exec('grep "LE_WORKING_DIR" ' . escapeshellarg($env_file) . ' | ' . $cut, $output);
|
||||
@@ -525,11 +541,15 @@ EOC;
|
||||
return FileDir::makeCorrectDir($output[0] . "/" . $domain);
|
||||
}
|
||||
}
|
||||
return FileDir::makeCorrectDir(dirname(self::$acmesh) . "/" . $domain);
|
||||
return FileDir::makeCorrectDir(dirname(self::getAcmeSh()) . "/" . $domain);
|
||||
}
|
||||
|
||||
public static function getAcmeSh()
|
||||
{
|
||||
$from_settings = Settings::Get('system.acmeshpath');
|
||||
if (file_exists($from_settings)) {
|
||||
return $from_settings;
|
||||
}
|
||||
return self::$acmesh;
|
||||
}
|
||||
|
||||
@@ -583,16 +603,24 @@ EOC;
|
||||
*/
|
||||
private static function checkInstall($tries = 0)
|
||||
{
|
||||
if (! file_exists(self::$acmesh) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::$acmesh . "'" . PHP_EOL;
|
||||
if (! file_exists(self::getAcmeSh()) && $tries > 0) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_ERR, "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'");
|
||||
echo PHP_EOL . "Download/installation of acme.sh seems to have failed. Re-run cronjob to try again or install manually to '" . self::getAcmeSh() . "'" . PHP_EOL;
|
||||
return false;
|
||||
} else if (! file_exists(self::$acmesh)) {
|
||||
} else if (! file_exists(self::getAcmeSh())) {
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Could not find acme.sh - installing it to /root/.acme.sh/");
|
||||
$return = false;
|
||||
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh", $return, array(
|
||||
\Froxlor\FileDir::safe_exec("wget -O - https://get.acme.sh | sh -s email=" . Settings::Get('panel.adminmail'), $return, array(
|
||||
'|'
|
||||
));
|
||||
$set_path = self::getAcmeSh();
|
||||
// after this, regardless of what the user specified, the acme.sh installation will be in /root/.acme.sh
|
||||
if ($set_path != '/root/.acme.sh/acme.sh') {
|
||||
Settings::Set('system.acmeshpath', '/root/.acme.sh/acme.sh', true);
|
||||
// let the user know
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_WARNING, "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'");
|
||||
echo PHP_EOL . "Acme.sh could not be found in '" . $set_path . "' so froxlor installed it to the default location, which is '/root/.acme.sh/'" . PHP_EOL;
|
||||
}
|
||||
// check whether the installation worked
|
||||
return self::checkInstall(++ $tries);
|
||||
}
|
||||
@@ -604,9 +632,9 @@ EOC;
|
||||
*/
|
||||
private static function checkUpgrade()
|
||||
{
|
||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::$acmesh . " --upgrade --auto-upgrade 0");
|
||||
$acmesh_result = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --upgrade --auto-upgrade 0");
|
||||
// check for activated cron
|
||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::$acmesh . " --install-cronjob");
|
||||
$acmesh_result2 = \Froxlor\FileDir::safe_exec(self::getAcmeSh() . " --install-cronjob");
|
||||
FroxlorLogger::getInstanceOf()->logAction(FroxlorLogger::CRON_ACTION, LOG_INFO, "Checking for LetsEncrypt client upgrades before renewing certificates:\n" . implode("\n", $acmesh_result) . "\n" . implode("\n", $acmesh_result2));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -678,7 +678,7 @@ class Lighttpd extends HttpConfigBase
|
||||
// After inserting the AWStats information,
|
||||
// be sure to build the awstats conf file as well
|
||||
// and chown it using $awstats_params, #258
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the informations
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the information
|
||||
\Froxlor\Http\Statistics::createAWStatsConf(Settings::Get('system.logfiles_directory') . $domain['loginname'] . $speciallogfile . '-access.log', $domain['domain'], $alias . $server_alias, $domain['customerroot'], $domain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,7 +1153,7 @@ class Nginx extends HttpConfigBase
|
||||
// After inserting the AWStats information,
|
||||
// be sure to build the awstats conf file as well
|
||||
// and chown it using $awstats_params, #258
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the informations
|
||||
// Bug 960 + Bug 970 : Use full $domain instead of custom $awstats_params as following classes depend on the information
|
||||
\Froxlor\Http\Statistics::createAWStatsConf(Settings::Get('system.logfiles_directory') . $domain['loginname'] . $speciallogfile . '-access.log', $domain['domain'], $alias . $server_alias, $domain['customerroot'], $domain);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ class Fcgid
|
||||
// Set Binary
|
||||
$starter_file .= "exec " . $phpconfig['binary'] . " -c " . escapeshellarg($this->getConfigDir()) . "\n";
|
||||
|
||||
// remove +i attibute, so starter can be overwritten
|
||||
// remove +i attribute, so starter can be overwritten
|
||||
if (file_exists($this->getStarterFile())) {
|
||||
\Froxlor\FileDir::removeImmutable($this->getStarterFile());
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ class Fpm
|
||||
$openbasedir .= $_phpappendopenbasedir;
|
||||
}
|
||||
}
|
||||
$fpm_config .= 'php_admin_value[session.save_path] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
|
||||
|
||||
$fpm_config .= 'php_admin_value[upload_tmp_dir] = ' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('phpfpm.tmpdir') . '/' . $this->domain['loginname'] . '/') . "\n";
|
||||
|
||||
$admin = $this->getAdminData($this->domain['adminid']);
|
||||
@@ -261,6 +261,11 @@ class Fpm
|
||||
$fpm_config .= 'php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f ' . $this->domain['email'] . "\n";
|
||||
}
|
||||
|
||||
// check for session.save_path, whether it has been specified by the user, if not, set a default
|
||||
if (strpos($fpm_config, 'php_value[session.save_path]') === false && strpos($fpm_config, 'php_admin_value[session.save_path]') === false) {
|
||||
$fpm_config .= 'php_admin_value[session.save_path] = ' . $this->getTempDir() . "\n";
|
||||
}
|
||||
|
||||
// append custom phpfpm configuration
|
||||
if (! empty($fpm_custom_config)) {
|
||||
$fpm_config .= "\n; Custom Configuration\n";
|
||||
|
||||
@@ -24,6 +24,13 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
|
||||
private static $debugHandler = null;
|
||||
|
||||
private static $noncron_params = [
|
||||
'force',
|
||||
'debug',
|
||||
'no-fork',
|
||||
'run-task'
|
||||
];
|
||||
|
||||
public static function setArguments($argv = null)
|
||||
{
|
||||
self::$argv = $argv;
|
||||
@@ -47,6 +54,7 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
echo "--run-task\t\trun a specific task [1 = re-generate configs, 4 = re-generate dns zones, 10 = re-set quotas, 99 = re-create cron.d-file]\n";
|
||||
echo "--debug\t\t\toutput debug information about what is going on to STDOUT.\n";
|
||||
echo "--no-fork\t\tdo not fork to backkground (traffic cron only).\n\n";
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,13 +71,13 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
if (strtolower($argv[$x]) == '--force') {
|
||||
// really force re-generating of config-files by
|
||||
// inserting task 1
|
||||
\Froxlor\System\Cronjob::inserttask('1');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
|
||||
// bind (if enabled, \Froxlor\System\Cronjob::inserttask() checks this)
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
// set quotas (if enabled)
|
||||
\Froxlor\System\Cronjob::inserttask('10');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
|
||||
// also regenerate cron.d-file
|
||||
\Froxlor\System\Cronjob::inserttask('99');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
|
||||
array_push($jobs_to_run, 'tasks');
|
||||
define('CRON_IS_FORCED', 1);
|
||||
} elseif (strtolower($argv[$x]) == '--debug') {
|
||||
@@ -161,7 +169,7 @@ class MasterCron extends \Froxlor\Cron\FroxlorCron
|
||||
$crontype = "";
|
||||
if (isset(self::$argv) && is_array(self::$argv) && count(self::$argv) > 1) {
|
||||
for ($x = 1; $x < count(self::$argv); $x ++) {
|
||||
if (substr(strtolower(self::$argv[$x]), 0, 2) == '--' && strlen(self::$argv[$x]) > 3) {
|
||||
if (substr(self::$argv[$x], 0, 2) == '--' && strlen(self::$argv[$x]) > 3 && !in_array(substr(strtolower(self::$argv[$x]), 2),self::$noncron_params)) {
|
||||
$crontype = substr(strtolower(self::$argv[$x]), 2);
|
||||
$basename .= "-" . $crontype;
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Froxlor\Cron\System;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
@@ -25,12 +26,13 @@ class Extrausers
|
||||
// passwd
|
||||
$passwd = '/var/lib/extrausers/passwd';
|
||||
$sql = "SELECT customerid,username,'x' as password,uid,gid,'Froxlor User' as comment,homedir,shell, login_enabled FROM ftp_users ORDER BY uid, LENGTH(username) ASC";
|
||||
self::generateFile($passwd, $sql, $cronlog);
|
||||
$users_list = [];
|
||||
self::generateFile($passwd, $sql, $cronlog, $users_list);
|
||||
|
||||
// group
|
||||
$group = '/var/lib/extrausers/group';
|
||||
$sql = "SELECT groupname,'x' as password,gid,members FROM ftp_groups ORDER BY gid ASC";
|
||||
self::generateFile($group, $sql, $cronlog);
|
||||
self::generateFile($group, $sql, $cronlog, $users_list);
|
||||
|
||||
// shadow
|
||||
$shadow = '/var/lib/extrausers/shadow';
|
||||
@@ -44,7 +46,7 @@ class Extrausers
|
||||
@chmod('/var/lib/extrausers/shadow', 0640);
|
||||
}
|
||||
|
||||
private static function generateFile($file, $query, &$cronlog)
|
||||
private static function generateFile($file, $query, &$cronlog, &$result_list = null)
|
||||
{
|
||||
$type = basename($file);
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Creating ' . $type . ' file');
|
||||
@@ -74,6 +76,9 @@ class Extrausers
|
||||
$u['comment'] = 'Locked Froxlor User';
|
||||
}
|
||||
$line = $u['username'] . ':' . $u['password'] . ':' . $u['uid'] . ':' . $u['gid'] . ':' . $u['comment'] . ':' . $u['homedir'] . ':' . $u['shell'] . PHP_EOL;
|
||||
if (is_array($result_list)) {
|
||||
$result_list[] = $u['username'];
|
||||
}
|
||||
break;
|
||||
case 'group':
|
||||
$line = $u['groupname'] . ':' . $u['password'] . ':' . $u['gid'] . ':' . $u['members'] . PHP_EOL;
|
||||
@@ -84,6 +89,19 @@ class Extrausers
|
||||
}
|
||||
$data_content .= $line;
|
||||
}
|
||||
|
||||
// check for local group to generate
|
||||
if ($type == 'group' && Settings::Get('system.froxlorusergroup') != '') {
|
||||
$guid = intval(Settings::Get('system.froxlorusergroup_gid'));
|
||||
if (empty($guid)) {
|
||||
$guid = intval(Settings::Get('system.lastguid')) + 1;
|
||||
Settings::Set('system.lastguid', $guid, true);
|
||||
Settings::Set('system.froxlorusergroup_gid', $guid, true);
|
||||
}
|
||||
$line = Settings::Get('system.froxlorusergroup') . ':x:' . $guid . ':' . implode(',', $result_list) . PHP_EOL;
|
||||
$data_content .= $line;
|
||||
}
|
||||
|
||||
if (file_put_contents($file, $data_content) !== false) {
|
||||
$cronlog->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, 'Succesfully wrote ' . $type . ' file');
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace Froxlor\Cron\System;
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\Settings;
|
||||
|
||||
use Froxlor\Cron\TaskId;
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2003-2009 the SysCP Team (see authors).
|
||||
@@ -45,55 +47,55 @@ class TasksCron extends \Froxlor\Cron\FroxlorCron
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
if ($row['type'] == '1') {
|
||||
if ($row['type'] == TaskId::REBUILD_VHOST) {
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
self::rebuildWebserverConfigs();
|
||||
} elseif ($row['type'] == '2') {
|
||||
} elseif ($row['type'] == TaskId::CREATE_HOME) {
|
||||
/**
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
self::createNewHome($row);
|
||||
} elseif ($row['type'] == '4' && (int) Settings::Get('system.bind_enable') != 0) {
|
||||
} elseif ($row['type'] == TaskId::REBUILD_DNS && (int) Settings::Get('system.bind_enable') != 0) {
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE BIND CONFIG HAS CHANGED.
|
||||
* REBUILD froxlor_bind.conf IF BIND IS ENABLED
|
||||
*/
|
||||
self::rebuildDnsConfigs();
|
||||
} elseif ($row['type'] == '5') {
|
||||
} elseif ($row['type'] == TaskId::CREATE_FTP) {
|
||||
/**
|
||||
* TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY
|
||||
*/
|
||||
self::createNewFtpHome($row);
|
||||
} elseif ($row['type'] == '6') {
|
||||
} elseif ($row['type'] == TaskId::DELETE_CUSTOMER_FILES) {
|
||||
/**
|
||||
* TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES
|
||||
*/
|
||||
self::deleteCustomerData($row);
|
||||
} elseif ($row['type'] == '7') {
|
||||
} elseif ($row['type'] == TaskId::DELETE_EMAIL_DATA) {
|
||||
/**
|
||||
* TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem
|
||||
*/
|
||||
self::deleteEmailData($row);
|
||||
} elseif ($row['type'] == '8') {
|
||||
} elseif ($row['type'] == TaskId::DELETE_FTP_DATA) {
|
||||
/**
|
||||
* TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem
|
||||
* refs #293
|
||||
*/
|
||||
self::deleteFtpData($row);
|
||||
} elseif ($row['type'] == '10' && (int) Settings::Get('system.diskquota_enabled') != 0) {
|
||||
} elseif ($row['type'] == TaskId::CREATE_QUOTA && (int) Settings::Get('system.diskquota_enabled') != 0) {
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
self::setFilesystemQuota();
|
||||
} elseif ($row['type'] == '11' && Settings::Get('system.dns_server') == 'PowerDNS') {
|
||||
} elseif ($row['type'] == TaskId::DELETE_DOMAIN_PDNS && Settings::Get('system.dns_server') == 'PowerDNS') {
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_NOTICE, "Removing PowerDNS entries for domain " . $row['data']['domain']);
|
||||
\Froxlor\Dns\PowerDNS::cleanDomainZone($row['data']['domain']);
|
||||
} elseif ($row['type'] == '12') {
|
||||
} elseif ($row['type'] == TaskId::DELETE_DOMAIN_SSL) {
|
||||
/**
|
||||
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
|
||||
*/
|
||||
|
||||
105
lib/Froxlor/Cron/TaskId.php
Normal file
105
lib/Froxlor/Cron/TaskId.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace Froxlor\Cron;
|
||||
|
||||
|
||||
class TaskId {
|
||||
/**
|
||||
* TYPE=1 MEANS TO REBUILD APACHE VHOSTS.CONF
|
||||
*/
|
||||
const REBUILD_VHOST = 1;
|
||||
|
||||
/**
|
||||
* TYPE=2 MEANS TO CREATE A NEW HOME AND CHOWN
|
||||
*/
|
||||
const CREATE_HOME = 2;
|
||||
|
||||
/**
|
||||
* TYPE=4 MEANS THAT SOMETHING IN THE DNS CONFIG HAS CHANGED.
|
||||
* REBUILD froxlor_bind.conf IF BIND IS ENABLED, UPDATE DKIM KEYS
|
||||
*/
|
||||
const REBUILD_DNS = 4;
|
||||
|
||||
/**
|
||||
* TYPE=5 MEANS THAT A NEW FTP-ACCOUNT HAS BEEN CREATED, CREATE THE DIRECTORY
|
||||
*/
|
||||
const CREATE_FTP = 5;
|
||||
|
||||
/**
|
||||
* TYPE=6 MEANS THAT A CUSTOMER HAS BEEN DELETED AND THAT WE HAVE TO REMOVE ITS FILES
|
||||
*/
|
||||
const DELETE_CUSTOMER_FILES = 6;
|
||||
|
||||
/**
|
||||
* TYPE=7 Customer deleted an email account and wants the data to be deleted on the filesystem
|
||||
*/
|
||||
const DELETE_EMAIL_DATA = 7;
|
||||
|
||||
/**
|
||||
* TYPE=8 Customer deleted a ftp account and wants the homedir to be deleted on the filesystem
|
||||
* refs #293
|
||||
*/
|
||||
const DELETE_FTP_DATA = 8;
|
||||
|
||||
/**
|
||||
* TYPE=10 Set the filesystem - quota
|
||||
*/
|
||||
const CREATE_QUOTA = 10;
|
||||
|
||||
/**
|
||||
* TYPE=11 domain has been deleted, remove from pdns database if used
|
||||
*/
|
||||
const DELETE_DOMAIN_PDNS = 11;
|
||||
|
||||
/**
|
||||
* TYPE=12 domain has been deleted, remove from acme.sh/let's encrypt directory if used
|
||||
*/
|
||||
const DELETE_DOMAIN_SSL = 12;
|
||||
|
||||
/**
|
||||
* TYPE=20 COSTUMERBACKUP
|
||||
*/
|
||||
const CREATE_CUSTOMER_BACKUP = 20;
|
||||
|
||||
/**
|
||||
* TYPE=99 REGENERATE CRON
|
||||
*/
|
||||
const REBUILD_CRON = 99;
|
||||
|
||||
/**
|
||||
* Return if a cron task id is valid
|
||||
* @param int|string $id cron task id (legacy string support)
|
||||
* @return boolean
|
||||
*/
|
||||
public static function isValid($id) {
|
||||
static $reflContants;
|
||||
if (!is_numeric($id)) {
|
||||
return false;
|
||||
}
|
||||
$numericid = (int)$id;
|
||||
if (!is_array($reflContants)) {
|
||||
$reflClass = new \ReflectionClass(get_called_class());
|
||||
$reflContants = $reflClass->getConstants();
|
||||
}
|
||||
return in_array($numericid, $reflContants, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get constant name by id
|
||||
* @param int|string $id cron task id (legacy string support)
|
||||
* @return string|false constant name or false if not found
|
||||
*/
|
||||
public static function convertToConstant($id) {
|
||||
static $reflContants;
|
||||
if (!is_numeric($id)) {
|
||||
return false;
|
||||
}
|
||||
$numericid = (int)$id;
|
||||
if (!is_array($reflContants)) {
|
||||
$reflClass = new \ReflectionClass(get_called_class());
|
||||
$reflContants = $reflClass->getConstants();
|
||||
}
|
||||
return array_search($numericid, $reflContants, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class TrafficCron extends \Froxlor\Cron\FroxlorCron
|
||||
}
|
||||
|
||||
/**
|
||||
* TRAFFIC AND DISKUSAGE MESSURE
|
||||
* TRAFFIC AND DISKUSAGE MEASURE
|
||||
*/
|
||||
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_INFO, 'Traffic run started...');
|
||||
$admin_traffic = array();
|
||||
|
||||
@@ -165,7 +165,7 @@ class Database
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the sql-access data as array using indeces
|
||||
* returns the sql-access data as array using indices
|
||||
* 'user', 'passwd' and 'host'.
|
||||
* Returns false if not enabled
|
||||
*
|
||||
@@ -279,6 +279,8 @@ class Database
|
||||
$host = $sql_root[self::$dbserver]['host'];
|
||||
$socket = isset($sql_root[self::$dbserver]['socket']) ? $sql_root[self::$dbserver]['socket'] : null;
|
||||
$port = isset($sql_root[self::$dbserver]['port']) ? $sql_root[self::$dbserver]['port'] : '3306';
|
||||
$sslCAFile = $sql_root[self::$dbserver]['ssl']['caFile'] ?? "";
|
||||
$sslVerifyServerCertificate = $sql_root[self::$dbserver]['ssl']['verifyServerCertificate'] ?? false;
|
||||
} else {
|
||||
$caption = 'localhost';
|
||||
$user = $sql["user"];
|
||||
@@ -286,6 +288,8 @@ class Database
|
||||
$host = $sql["host"];
|
||||
$socket = isset($sql['socket']) ? $sql['socket'] : null;
|
||||
$port = isset($sql['port']) ? $sql['port'] : '3306';
|
||||
$sslCAFile = $sql['ssl']['caFile'] ?? "";
|
||||
$sslVerifyServerCertificate = $sql['ssl']['verifyServerCertificate'] ?? false;
|
||||
}
|
||||
|
||||
// save sql-access-data if needed
|
||||
@@ -297,7 +301,9 @@ class Database
|
||||
'port' => $port,
|
||||
'socket' => $socket,
|
||||
'db' => $sql["db"],
|
||||
'caption' => $caption
|
||||
'caption' => $caption,
|
||||
'ssl_ca_file' => $sslCAFile,
|
||||
'ssl_verify_server_certificate' => $sslVerifyServerCertificate
|
||||
);
|
||||
}
|
||||
|
||||
@@ -321,6 +327,11 @@ class Database
|
||||
} else {
|
||||
$dbconf["dsn"]['host'] = $host;
|
||||
$dbconf["dsn"]['port'] = $port;
|
||||
|
||||
if (!empty(self::$sqldata['ssl_ca_file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = self::$sqldata['ssl_ca_file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) self::$sqldata['ssl_verify_server_certificate'];
|
||||
}
|
||||
}
|
||||
|
||||
self::$dbname = $sql["db"];
|
||||
|
||||
@@ -82,11 +82,13 @@ class DbManager
|
||||
// get all usernames from db-manager
|
||||
$allsqlusers = $this->getManager()->getAllSqlUsers();
|
||||
// generate random username
|
||||
$username = $loginname . '-' . substr(md5(uniqid(microtime(), 1)), 20, 3);
|
||||
$username = $loginname . '-' . substr(\Froxlor\Froxlor::genSessionId(), 20, 3);
|
||||
// check whether it exists on the DBMS
|
||||
while (in_array($username, $allsqlusers)) {
|
||||
$username = $loginname . '-' . substr(md5(uniqid(microtime(), 1)), 20, 3);
|
||||
$username = $loginname . '-' . substr(\Froxlor\Froxlor::genSessionId(), 20, 3);
|
||||
}
|
||||
} elseif (strtoupper(Settings::Get('customer.mysqlprefix')) == 'DBNAME') {
|
||||
$username = $loginname;
|
||||
} else {
|
||||
$username = $loginname . Settings::Get('customer.mysqlprefix') . (intval($last_accnumber) + 1);
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ class IntegrityCheck
|
||||
'dbname' => Database::getDbName()
|
||||
));
|
||||
$charset = isset($resp['default_character_set_name']) ? $resp['default_character_set_name'] : null;
|
||||
if (! empty($charset) && strtolower($charset) != 'utf8') {
|
||||
if (! empty($charset) && substr(strtolower($charset), 0, 4) != 'utf8') {
|
||||
$this->log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "database charset seems to be different from UTF-8, integrity-check can fix that");
|
||||
if ($fix) {
|
||||
// fix database
|
||||
|
||||
@@ -53,7 +53,7 @@ class Dns
|
||||
$domain = $domain_id;
|
||||
}
|
||||
|
||||
if ($domain['isbinddomain'] != '1') {
|
||||
if (!isset($domain['isbinddomain']) || $domain['isbinddomain'] != '1') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class Dns
|
||||
if (! $isMainButSubTo) {
|
||||
self::addRequiredEntry('@', 'NS', $required_entries);
|
||||
}
|
||||
if ($domain['isemaildomain'] === '1') {
|
||||
if ($domain['isemaildomain'] == '1') {
|
||||
self::addRequiredEntry('@', 'MX', $required_entries);
|
||||
if (Settings::Get('system.dns_createmailentry')) {
|
||||
foreach (array(
|
||||
@@ -190,12 +190,26 @@ class Dns
|
||||
'@',
|
||||
'www',
|
||||
'*'
|
||||
] as $crceord) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crceord), $required_entries['A']) || array_key_exists(md5($crceord), $required_entries['AAAA']))) {
|
||||
unset($required_entries['A'][md5($crceord)]);
|
||||
unset($required_entries['AAAA'][md5($crceord)]);
|
||||
] as $crecord) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == '@' && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
|
||||
unset($required_entries['A'][md5($crecord)]);
|
||||
unset($required_entries['AAAA'][md5($crecord)]);
|
||||
}
|
||||
}
|
||||
// also allow overriding of auto-generated values (imap,pop3,mail,smtp) if enabled in the settings
|
||||
if (Settings::Get('system.dns_createmailentry')) {
|
||||
foreach (array(
|
||||
'imap',
|
||||
'pop3',
|
||||
'mail',
|
||||
'smtp'
|
||||
) as $crecord) {
|
||||
if ($entry['type'] == 'CNAME' && $entry['record'] == $crecord && (array_key_exists(md5($crecord), $required_entries['A']) || array_key_exists(md5($crecord), $required_entries['AAAA']))) {
|
||||
unset($required_entries['A'][md5($crecord)]);
|
||||
unset($required_entries['AAAA'][md5($crecord)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$zonerecords[] = new DnsEntry($entry['record'], $entry['type'], $entry['content'], $entry['prio'], $entry['ttl']);
|
||||
}
|
||||
|
||||
@@ -324,11 +338,28 @@ class Dns
|
||||
foreach ($records as $record) {
|
||||
if ($record == '@CAA@') {
|
||||
$caa_entries = explode(PHP_EOL, Settings::Get('caa.caa_entry'));
|
||||
if ($domain['letsencrypt'] == 1) {
|
||||
$le_entry = $domain['iswildcarddomain'] == '1' ? '0 issuewild "letsencrypt.org"' : '0 issue "letsencrypt.org"';
|
||||
array_push($caa_entries, $le_entry);
|
||||
$caa_domain = "letsencrypt.org";
|
||||
if (Settings::Get('system.letsencryptca') == 'buypass' || Settings::Get('system.letsencryptca') == 'buypass_test') {
|
||||
$caa_domain = "buypass.com";
|
||||
}
|
||||
if ($domain['letsencrypt'] == 1) {
|
||||
if (Settings::Get('system.letsencryptca') == 'zerossl') {
|
||||
$caa_domains = [
|
||||
"sectigo.com",
|
||||
"trust-provider.com",
|
||||
"usertrust.com",
|
||||
"comodoca.com",
|
||||
"comodo.com"
|
||||
];
|
||||
foreach ($caa_domains as $caa_domain) {
|
||||
$le_entry = $domain['iswildcarddomain'] == '1' ? '0 issuewild "' . $caa_domain . '"' : '0 issue "' . $caa_domain . '"';
|
||||
array_push($caa_entries, $le_entry);
|
||||
}
|
||||
} else {
|
||||
$le_entry = $domain['iswildcarddomain'] == '1' ? '0 issuewild "' . $caa_domain . '"' : '0 issue "' . $caa_domain . '"';
|
||||
array_push($caa_entries, $le_entry);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($caa_entries as $entry) {
|
||||
if (empty($entry)) continue;
|
||||
$zonerecords[] = new DnsEntry('@', 'CAA', $entry);
|
||||
@@ -372,7 +403,7 @@ class Dns
|
||||
$soa_content = $primary_ns . " " . self::escapeSoaAdminMail($soa_email) . " ";
|
||||
$soa_content .= $domain['bindserial'] . " ";
|
||||
// TODO for now, dummy time-periods
|
||||
$soa_content .= "3600 900 604800 " . (int) Settings::Get('system.defaultttl');
|
||||
$soa_content .= "3600 900 1209600 1200";
|
||||
|
||||
$soa_record = new DnsEntry('@', 'SOA', $soa_content);
|
||||
array_unshift($zonerecords, $soa_record);
|
||||
|
||||
@@ -62,6 +62,11 @@ class PowerDNS
|
||||
} else {
|
||||
$dbconf["dsn"]['host'] = $mysql_data['gmysql-host'];
|
||||
$dbconf["dsn"]['port'] = $mysql_data['gmysql-port'];
|
||||
|
||||
if (!empty($mysql_data['gmysql-ssl-ca-file'])) {
|
||||
$options[\PDO::MYSQL_ATTR_SSL_CA] = $mysql_data['gmysql-ssl-ca-file'];
|
||||
$options[\PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT] = (bool) $mysql_data['gmysql-ssl-verify-server-certificate'];
|
||||
}
|
||||
}
|
||||
|
||||
// add options to dsn-string
|
||||
|
||||
@@ -340,7 +340,7 @@ class Domain
|
||||
// run remove command
|
||||
\Froxlor\FileDir::safe_exec($acmesh . $params);
|
||||
// remove certificates directory
|
||||
@unlink($certificate_folder);
|
||||
\Froxlor\FileDir::safe_exec('rm -rf ' . $certificate_folder);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -16,7 +16,7 @@ class FileDir
|
||||
* @param array $allowedChars
|
||||
* optional array of allowed characters in path/command
|
||||
*
|
||||
* @return string result of exec()
|
||||
* @return array result of exec()
|
||||
*/
|
||||
public static function safe_exec($exec_string, &$return_value = false, $allowedChars = null)
|
||||
{
|
||||
@@ -370,7 +370,7 @@ class FileDir
|
||||
* @param
|
||||
* integer uid The uid which must match the found directories
|
||||
* @param
|
||||
* integer gid The gid which must match the found direcotries
|
||||
* integer gid The gid which must match the found directories
|
||||
* @param
|
||||
* string value the value for the input-field
|
||||
*
|
||||
@@ -461,7 +461,7 @@ class FileDir
|
||||
* @param int $uid
|
||||
* the uid which must match the found directories
|
||||
* @param int $gid
|
||||
* the gid which must match the found direcotries
|
||||
* the gid which must match the found directories
|
||||
*
|
||||
* @return array Array of found valid paths
|
||||
*/
|
||||
|
||||
@@ -7,10 +7,10 @@ final class Froxlor
|
||||
{
|
||||
|
||||
// Main version variable
|
||||
const VERSION = '0.10.26';
|
||||
const VERSION = '0.10.33';
|
||||
|
||||
// Database version (YYYYMMDDC where C is a daily counter)
|
||||
const DBVERSION = '202103240';
|
||||
const DBVERSION = '202112310';
|
||||
|
||||
// Distribution branding-tag (used for Debian etc.)
|
||||
const BRANDING = '';
|
||||
@@ -202,6 +202,30 @@ final class Froxlor
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* generate safe unique session id
|
||||
*
|
||||
* @param int $length
|
||||
* @return string
|
||||
*/
|
||||
public static function genSessionId(int $length = 16)
|
||||
{
|
||||
if(!isset($length) || intval($length) <= 8 ){
|
||||
$length = 16;
|
||||
}
|
||||
if (function_exists('random_bytes')) {
|
||||
return bin2hex(random_bytes($length));
|
||||
}
|
||||
if (function_exists('mcrypt_create_iv')) {
|
||||
return bin2hex(mcrypt_create_iv($length, MCRYPT_DEV_URANDOM));
|
||||
}
|
||||
if (function_exists('openssl_random_pseudo_bytes')) {
|
||||
return bin2hex(openssl_random_pseudo_bytes($length));
|
||||
}
|
||||
// if everything else fails, use unsafe fallback
|
||||
return md5(uniqid(microtime(), 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* compare of froxlor versions
|
||||
*
|
||||
|
||||
@@ -157,7 +157,7 @@ class FroxlorLogger
|
||||
echo "[" . $this->getLogLevelDesc($type) . "] " . $text . PHP_EOL;
|
||||
}
|
||||
|
||||
// warnings, errors and critical mesages WILL be logged
|
||||
// warnings, errors and critical messages WILL be logged
|
||||
if (Settings::Get('logger.log_cron') == '0' && $action == \Froxlor\FroxlorLogger::CRON_ACTION && $type > LOG_WARNING) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -241,10 +241,14 @@ class PhpHelper
|
||||
$ips = array();
|
||||
foreach ($dns as $record) {
|
||||
if ($record["type"] == "A") {
|
||||
$ips[] = $record["ip"];
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($record["ip"]));
|
||||
$ips[] = $ip;
|
||||
}
|
||||
if ($record["type"] == "AAAA") {
|
||||
$ips[] = $record["ipv6"];
|
||||
// always use compressed ipv6 format
|
||||
$ip = inet_ntop(inet_pton($record["ipv6"]));
|
||||
$ips[] = $ip;
|
||||
}
|
||||
}
|
||||
if (count($ips) < 1) {
|
||||
|
||||
@@ -60,6 +60,13 @@ class SImExporter
|
||||
|
||||
public static function export()
|
||||
{
|
||||
$settings_definitions = [];
|
||||
foreach (\Froxlor\PhpHelper::loadConfigArrayDir('./actions/admin/settings/')['groups'] AS $group) {
|
||||
foreach ($group['fields'] AS $field) {
|
||||
$settings_definitions[$field['settinggroup']][$field['varname']] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
$result_stmt = Database::query("
|
||||
SELECT * FROM `" . TABLE_PANEL_SETTINGS . "` ORDER BY `settingid` ASC
|
||||
");
|
||||
@@ -69,13 +76,26 @@ class SImExporter
|
||||
if (! in_array($index, self::$no_export)) {
|
||||
$_data[$index] = $row['value'];
|
||||
}
|
||||
|
||||
if (array_key_exists($row['settinggroup'], $settings_definitions) && array_key_exists($row['varname'], $settings_definitions[$row['settinggroup']])) {
|
||||
// Export image file
|
||||
if ($settings_definitions[$row['settinggroup']][$row['varname']]['type'] === "image") {
|
||||
if ($row['value'] === "") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$_data[$index.'.image_data'] = base64_encode(file_get_contents(explode('?', $row['value'], 2)[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add checksum for validation
|
||||
$_data['_sha'] = sha1(var_export($_data, true));
|
||||
$_export = json_encode($_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
|
||||
if (! $_export) {
|
||||
throw new \Exception("Error exporting settings: " . json_last_error_msg());
|
||||
}
|
||||
|
||||
return $_export;
|
||||
}
|
||||
|
||||
@@ -98,7 +118,7 @@ class SImExporter
|
||||
if ($_sha != sha1(var_export($_data, true))) {
|
||||
throw new \Exception("SHA check of import data failed. Unable to import.");
|
||||
}
|
||||
// do not import version info - but we need that to possibily update settings
|
||||
// do not import version info - but we need that to possibly update settings
|
||||
// when there were changes in the variable-name or similar
|
||||
unset($_data['panel.version']);
|
||||
unset($_data['panel.db_version']);
|
||||
@@ -120,6 +140,26 @@ class SImExporter
|
||||
}
|
||||
// store new data
|
||||
foreach ($_data as $index => $value) {
|
||||
$index_split = explode('.', $index, 3);
|
||||
|
||||
// Catch image_data and save it
|
||||
if (isset($index_split[2]) && $index_split[2] === 'image_data' && !empty($_data[$index_split[0].'.'.$index_split[1]])) {
|
||||
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
|
||||
if (!is_dir($path) && !mkdir($path, 0775)) {
|
||||
throw new \Exception("img directory does not exist and cannot be created");
|
||||
}
|
||||
|
||||
// Make sure we can write to the upload directory
|
||||
if (!is_writable($path)) {
|
||||
if (!chmod($path, 0775)) {
|
||||
throw new \Exception("Cannot write to img directory");
|
||||
}
|
||||
}
|
||||
|
||||
file_put_contents(\Froxlor\Froxlor::getInstallDir() . '/' . explode('?', $_data[$index_split[0].'.'.$index_split[1]], 2)[0], base64_decode($value));
|
||||
continue;
|
||||
}
|
||||
|
||||
Settings::Set($index, $value);
|
||||
}
|
||||
// save to DB
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
namespace Froxlor\Settings;
|
||||
|
||||
use Froxlor\Database\Database;
|
||||
use Froxlor\FileDir;
|
||||
use Froxlor\Settings;
|
||||
|
||||
class Store
|
||||
@@ -174,7 +175,7 @@ class Store
|
||||
$returnvalue = self::storeSettingField($fieldname, $fielddata, $newfieldvalue);
|
||||
|
||||
if ($returnvalue !== false) {
|
||||
\Froxlor\System\Cronjob::inserttask('4');
|
||||
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
|
||||
}
|
||||
return $returnvalue;
|
||||
}
|
||||
@@ -367,4 +368,68 @@ class Store
|
||||
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
public static function storeSettingImage($fieldname, $fielddata)
|
||||
{
|
||||
if (isset($fielddata['settinggroup'], $fielddata['varname']) && is_array($fielddata) && $fielddata['settinggroup'] !== '' && $fielddata['varname'] !== '') {
|
||||
$save_to = null;
|
||||
$path = \Froxlor\Froxlor::getInstallDir().'/img/';
|
||||
$path = \Froxlor\FileDir::makeCorrectDir($path);
|
||||
|
||||
// New file?
|
||||
if (isset($_FILES[$fieldname]) && $_FILES[$fieldname]['tmp_name']) {
|
||||
// Make sure upload directory exists
|
||||
if (!is_dir($path) && !mkdir($path, 0775)) {
|
||||
throw new \Exception("img directory does not exist and cannot be created");
|
||||
}
|
||||
|
||||
// Make sure we can write to the upload directory
|
||||
if (!is_writable($path)) {
|
||||
if (!chmod($path, 0775)) {
|
||||
throw new \Exception("Cannot write to img directory");
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure mime-type matches an image
|
||||
if (!in_array(mime_content_type($_FILES[$fieldname]['tmp_name']), ['image/jpeg','image/jpg','image/png','image/gif'])) {
|
||||
throw new \Exception("Uploaded file not a valid image");
|
||||
}
|
||||
|
||||
// Determine file extension
|
||||
$spl = explode('.', $_FILES[$fieldname]['name']);
|
||||
$file_extension = strtolower(array_pop($spl));
|
||||
unset($spl);
|
||||
|
||||
// Move file
|
||||
if (!move_uploaded_file($_FILES[$fieldname]['tmp_name'], $path.$fielddata['image_name'].'.'.$file_extension)) {
|
||||
throw new \Exception("Unable to save image to img folder");
|
||||
}
|
||||
|
||||
$save_to = 'img/'.$fielddata['image_name'].'.'.$file_extension.'?v='.time();
|
||||
}
|
||||
|
||||
// Delete file?
|
||||
if ($fielddata['value'] !== "" && array_key_exists($fieldname.'_delete', $_POST) && $_POST[$fieldname.'_delete']) {
|
||||
@unlink(\Froxlor\Froxlor::getInstallDir() . '/' . explode('?', $fielddata['value'], 2)[0]);
|
||||
$save_to = '';
|
||||
}
|
||||
|
||||
// Nothing changed
|
||||
if ($save_to === null) {
|
||||
return array(
|
||||
$fielddata['settinggroup'] . '.' . $fielddata['varname'] => $fielddata['value']
|
||||
);
|
||||
}
|
||||
|
||||
if (Settings::Set($fielddata['settinggroup'] . '.' . $fielddata['varname'], $save_to) === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return array(
|
||||
$fielddata['settinggroup'] . '.' . $fielddata['varname'] => $save_to
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace Froxlor\System;
|
||||
use Froxlor\Settings;
|
||||
use Froxlor\Database\Database;
|
||||
|
||||
use Froxlor\Cron\TaskId;
|
||||
|
||||
class Cronjob
|
||||
{
|
||||
|
||||
@@ -93,29 +95,25 @@ class Cronjob
|
||||
* @param
|
||||
* int Type of task
|
||||
* @param
|
||||
* string Parameter 1
|
||||
* @param
|
||||
* string Parameter 2
|
||||
* @param
|
||||
* string Parameter 3
|
||||
* string Parameter (possible to pass multiple times)
|
||||
*
|
||||
* @author Florian Lippert <flo@syscp.org>
|
||||
* @author Froxlor team <team@froxlor.org>
|
||||
*/
|
||||
public static function inserttask($type, $param1 = '', $param2 = '', $param3 = '', $param4 = '')
|
||||
public static function inserttask($type, ...$params)
|
||||
{
|
||||
|
||||
// prepare the insert-statement
|
||||
$ins_stmt = Database::prepare("
|
||||
INSERT INTO `" . TABLE_PANEL_TASKS . "` SET `type` = :type, `data` = :data
|
||||
");
|
||||
|
||||
if ($type == '1' || $type == '3' || $type == '4' || $type == '5' || $type == '10' || $type == '99') {
|
||||
if ($type == TaskId::REBUILD_VHOST || $type == TaskId::REBUILD_DNS || $type == TaskId::CREATE_FTP || $type == TaskId::CREATE_QUOTA || $type == TaskId::REBUILD_CRON) {
|
||||
// 4 = bind -> if bind disabled -> no task
|
||||
if ($type == '4' && Settings::Get('system.bind_enable') == '0') {
|
||||
if ($type == TaskId::REBUILD_DNS && Settings::Get('system.bind_enable') == '0') {
|
||||
return;
|
||||
}
|
||||
// 10 = quota -> if quota disabled -> no task
|
||||
if ($type == '10' && Settings::Get('system.diskquota_enabled') == '0') {
|
||||
if ($type == TaskId::CREATE_QUOTA && Settings::Get('system.diskquota_enabled') == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -132,64 +130,64 @@ class Cronjob
|
||||
'type' => $type,
|
||||
'data' => ''
|
||||
));
|
||||
} elseif ($type == '2' && $param1 != '' && $param2 != '' && $param3 != '' && ($param4 == 0 || $param4 == 1)) {
|
||||
} elseif ($type == TaskId::CREATE_HOME && count($params) == 4 && $params[0] != '' && $params[1] != '' && $params[2] != '' && ($params[3] == 0 || $params[3] == 1)) {
|
||||
$data = array();
|
||||
$data['loginname'] = $param1;
|
||||
$data['uid'] = $param2;
|
||||
$data['gid'] = $param3;
|
||||
$data['store_defaultindex'] = $param4;
|
||||
$data['loginname'] = $params[0];
|
||||
$data['uid'] = $params[1];
|
||||
$data['gid'] = $params[2];
|
||||
$data['store_defaultindex'] = $params[3];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '2',
|
||||
'type' => TaskId::CREATE_HOME,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '6' && $param1 != '') {
|
||||
} elseif ($type == TaskId::DELETE_CUSTOMER_FILES && isset($params[0]) && $params[0] != '') {
|
||||
$data = array();
|
||||
$data['loginname'] = $param1;
|
||||
$data['loginname'] = $params[0];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '6',
|
||||
'type' => TaskId::DELETE_CUSTOMER_FILES,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '7' && $param1 != '' && $param2 != '') {
|
||||
} elseif ($type == TaskId::DELETE_EMAIL_DATA && count($params) == 2 && $params[0] != '' && $params[1] != '') {
|
||||
$data = array();
|
||||
$data['loginname'] = $param1;
|
||||
$data['email'] = $param2;
|
||||
$data['loginname'] = $params[0];
|
||||
$data['email'] = $params[1];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '7',
|
||||
'type' => TaskId::DELETE_EMAIL_DATA,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '8' && $param1 != '' && $param2 != '') {
|
||||
} elseif ($type == TaskId::DELETE_FTP_DATA && count($params) == 2 && $params[0] != '' && $params[1] != '') {
|
||||
$data = array();
|
||||
$data['loginname'] = $param1;
|
||||
$data['homedir'] = $param2;
|
||||
$data['loginname'] = $params[0];
|
||||
$data['homedir'] = $params[1];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '8',
|
||||
'type' => TaskId::DELETE_FTP_DATA,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '11' && $param1 != '' && Settings::Get('system.bind_enable') == '1' && Settings::Get('system.dns_server') == 'PowerDNS') {
|
||||
} elseif ($type == TaskId::DELETE_DOMAIN_PDNS && isset($params[0]) && $params[0] != '' && Settings::Get('system.bind_enable') == '1' && Settings::Get('system.dns_server') == 'PowerDNS') {
|
||||
// -> if bind disabled or dns-server not PowerDNS -> no task
|
||||
$data = array();
|
||||
$data['domain'] = $param1;
|
||||
$data['domain'] = $params[0];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '11',
|
||||
'type' => TaskId::DELETE_DOMAIN_PDNS,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '12' && $param1 != '') {
|
||||
} elseif ($type == TaskId::DELETE_DOMAIN_SSL && isset($params[0]) && $params[0] != '') {
|
||||
$data = array();
|
||||
$data['domain'] = $param1;
|
||||
$data['domain'] = $params[0];
|
||||
$data = json_encode($data);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '12',
|
||||
'type' => TaskId::DELETE_DOMAIN_SSL,
|
||||
'data' => $data
|
||||
));
|
||||
} elseif ($type == '20' && is_array($param1)) {
|
||||
$data = json_encode($param1);
|
||||
} elseif ($type == TaskId::CREATE_CUSTOMER_BACKUP && isset($params[0]) && is_array($params[0])) {
|
||||
$data = json_encode($params[0]);
|
||||
Database::pexecute($ins_stmt, array(
|
||||
'type' => '20',
|
||||
'type' => TaskId::CREATE_CUSTOMER_BACKUP,
|
||||
'data' => $data
|
||||
));
|
||||
}
|
||||
@@ -248,57 +246,23 @@ class Cronjob
|
||||
$row['data'] = json_decode($row['data'], true);
|
||||
}
|
||||
|
||||
// rebuilding webserver-configuration
|
||||
if ($row['type'] == '1') {
|
||||
$task_desc = $lng['tasks']['rebuild_webserverconfig'];
|
||||
} elseif ($row['type'] == '2') {
|
||||
// adding new user/
|
||||
$loginname = '';
|
||||
$task_id = $row['type'];
|
||||
if (\Froxlor\Cron\TaskId::isValid($task_id)) {
|
||||
$task_constname = \Froxlor\Cron\TaskId::convertToConstant($task_id);
|
||||
$task_desc = isset($lng['tasks'][$task_constname]) ? $lng['tasks'][$task_constname] : $task_constname;
|
||||
|
||||
if (is_array($row['data'])) {
|
||||
$loginname = $row['data']['loginname'];
|
||||
// task includes loginname
|
||||
if (isset($row['data']['loginname'])) {
|
||||
$loginname = $row['data']['loginname'];
|
||||
$task_desc = str_replace('%loginname%', $loginname, $task_desc);
|
||||
}
|
||||
// task includes domain data
|
||||
if (isset($row['data']['domain'])) {
|
||||
$domain = $row['data']['domain'];
|
||||
$task_desc = str_replace('%domain%', $domain, $task_desc);
|
||||
}
|
||||
}
|
||||
$task_desc = $lng['tasks']['adding_customer'];
|
||||
$task_desc = str_replace('%loginname%', $loginname, $task_desc);
|
||||
} elseif ($row['type'] == '4') {
|
||||
// rebuilding bind-configuration
|
||||
$task_desc = $lng['tasks']['rebuild_bindconfig'];
|
||||
} elseif ($row['type'] == '5') {
|
||||
// creating ftp-user directory
|
||||
$task_desc = $lng['tasks']['creating_ftpdir'];
|
||||
} elseif ($row['type'] == '6') {
|
||||
// deleting user-files
|
||||
$loginname = '';
|
||||
if (is_array($row['data'])) {
|
||||
$loginname = $row['data']['loginname'];
|
||||
}
|
||||
$task_desc = $lng['tasks']['deleting_customerfiles'];
|
||||
$task_desc = str_replace('%loginname%', $loginname, $task_desc);
|
||||
} elseif ($row['type'] == '7') {
|
||||
// deleting email-account
|
||||
$task_desc = $lng['tasks']['remove_emailacc_files'];
|
||||
} elseif ($row['type'] == '8') {
|
||||
// deleting ftp-account
|
||||
$task_desc = $lng['tasks']['remove_ftpacc_files'];
|
||||
} elseif ($row['type'] == '10') {
|
||||
// Set FS - quota
|
||||
$task_desc = $lng['tasks']['diskspace_set_quota'];
|
||||
} elseif ($row['type'] == '11') {
|
||||
// remove domain from pdns database if used
|
||||
$task_desc = sprintf($lng['tasks']['remove_pdns_domain'], $row['data']['domain']);
|
||||
} elseif ($row['type'] == '12') {
|
||||
// remove domains ssl files
|
||||
$task_desc = sprintf($lng['tasks']['remove_ssl_domain'], $row['data']['domain']);
|
||||
} elseif ($row['type'] == '20') {
|
||||
// deleting user-files
|
||||
$loginname = '';
|
||||
if (is_array($row['data'])) {
|
||||
$loginname = $row['data']['loginname'];
|
||||
}
|
||||
$task_desc = $lng['tasks']['backup_customerfiles'];
|
||||
$task_desc = str_replace('%loginname%', $loginname, $task_desc);
|
||||
} elseif ($row['type'] == '99') {
|
||||
// re-generating of cron.d-file
|
||||
$task_desc = $lng['tasks']['regenerating_crond'];
|
||||
} else {
|
||||
// unknown
|
||||
$task_desc = "ERROR: Unknown task type '" . $row['type'] . "'";
|
||||
|
||||
@@ -59,20 +59,20 @@ class Crypt
|
||||
}
|
||||
|
||||
/**
|
||||
* Make crypted password from clear text password
|
||||
* Make encrypted password from clear text password
|
||||
*
|
||||
* @author Michal Wojcik <m.wojcik@sonet3.pl>
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
*
|
||||
* 0 - default crypt (depenend on system configuration)
|
||||
* 0 - default crypt (depends on system configuration)
|
||||
* 1 - MD5 $1$
|
||||
* 2 - BLOWFISH $2y$07$
|
||||
* 3 - SHA-256 $5$ (default)
|
||||
* 4 - SHA-512 $6$
|
||||
*
|
||||
* @param string $password
|
||||
* Password to be crypted
|
||||
* Password to be encrypted
|
||||
* @param bool $htpasswd
|
||||
* optional whether to generate a SHA1 password for directory protection
|
||||
*
|
||||
|
||||
@@ -7,7 +7,7 @@ class Mailer extends \PHPMailer\PHPMailer\PHPMailer
|
||||
{
|
||||
|
||||
/**
|
||||
* class construtor
|
||||
* class constructor
|
||||
*
|
||||
* @param string $exceptions
|
||||
* whether to throw exceptions or not
|
||||
|
||||
@@ -52,6 +52,12 @@ class Data
|
||||
return $newfieldvalue;
|
||||
}
|
||||
|
||||
public static function getFormFieldDataImage($fieldname, $fielddata, $input)
|
||||
{
|
||||
// We always make the system think we have new data to trigger the save function where we actually check everything
|
||||
return time();
|
||||
}
|
||||
|
||||
public static function manipulateFormFieldDataDate($fieldname, $fielddata, $newfieldvalue)
|
||||
{
|
||||
if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) {
|
||||
|
||||
@@ -89,6 +89,15 @@ class Fields
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
public static function getFormFieldOutputImage($fieldname, $fielddata, $do_show = true)
|
||||
{
|
||||
global $lng;
|
||||
$label = $fielddata['label'];
|
||||
$value = htmlentities($fielddata['value']);
|
||||
eval("\$returnvalue = \"" . \Froxlor\UI\Template::getTemplate("formfields/image", true) . "\";");
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
public static function getFormFieldOutputDate($fieldname, $fielddata, $do_show = true)
|
||||
{
|
||||
if (isset($fielddata['date_timestamp']) && $fielddata['date_timestamp'] === true) {
|
||||
|
||||
@@ -269,7 +269,7 @@ class HTML
|
||||
}
|
||||
|
||||
$text = strtr($text, array(
|
||||
'%s' => $targetname
|
||||
'%s' => htmlspecialchars($targetname)
|
||||
));
|
||||
eval("echo \"" . Template::getTemplate('misc/question_yesno', '1') . "\";");
|
||||
exit();
|
||||
@@ -302,7 +302,7 @@ class HTML
|
||||
}
|
||||
|
||||
$text = strtr($text, array(
|
||||
'%s' => $targetname
|
||||
'%s' => htmlspecialchars($targetname)
|
||||
));
|
||||
eval("echo \"" . Template::getTemplate('misc/question_yesno_checkbox', '1') . "\";");
|
||||
exit();
|
||||
|
||||
@@ -77,7 +77,7 @@ class User
|
||||
}
|
||||
|
||||
/**
|
||||
* Function which updates all counters of used ressources in panel_admins and panel_customers
|
||||
* Function which updates all counters of used resources in panel_admins and panel_customers
|
||||
*
|
||||
* @param bool $returndebuginfo
|
||||
* Set to true to get an array with debug information
|
||||
@@ -237,7 +237,7 @@ class User
|
||||
$admin_domains = Database::pexecute_first($admin_domains_stmt, array(
|
||||
"aid" => $admin['adminid']
|
||||
));
|
||||
// substract the amount of domains that are std-subdomains later when we iterated through all customers and know for sure
|
||||
// subtract the amount of domains that are std-subdomains later when we iterated through all customers and know for sure
|
||||
$admin['domains_used_new'] = $admin_domains['number_domains'];
|
||||
// set current admin
|
||||
$cur_adm = $admin['adminid'];
|
||||
|
||||
@@ -74,7 +74,7 @@ class Check
|
||||
|
||||
public static function checkMysqlAccessHost($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
$mysql_access_host_array = array_map('trim', explode(',', $newfieldvalue));
|
||||
$mysql_access_host_array = array_unique(array_map('trim', explode(',', $newfieldvalue)));
|
||||
|
||||
foreach ($mysql_access_host_array as $host_entry) {
|
||||
if (Validate::validate_ip2($host_entry, true, 'invalidip', true, true, true, true, false) == false && Validate::validateDomain($host_entry) == false && Validate::validateLocalHostname($host_entry) == false && $host_entry != '%') {
|
||||
@@ -207,4 +207,30 @@ class Check
|
||||
}
|
||||
return $returnvalue;
|
||||
}
|
||||
|
||||
public static function checkLocalGroup($fieldname, $fielddata, $newfieldvalue, $allnewfieldvalues)
|
||||
{
|
||||
if (empty($newfieldvalue) || $fielddata == $newfieldvalue) {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
|
||||
];
|
||||
} elseif (function_exists('posix_getgrnam') && posix_getgrnam($newfieldvalue) == false) {
|
||||
if (Validate::validateUsername($newfieldvalue, Settings::Get('panel.unix_names'), 32)) {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_OK
|
||||
];
|
||||
} else {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||
'local_group_invalid'
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$returnvalue = [
|
||||
self::FORMFIELDS_PLAUSIBILITY_CHECK_ERROR,
|
||||
'local_group_exists'
|
||||
];
|
||||
}
|
||||
return $returnvalue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ class Validate
|
||||
|
||||
const REGEX_CONF_TEXT = '/^[^\0]*$/';
|
||||
|
||||
const REGEX_DESC_TEXT = '/^[^\0\r\n<>]*$/';
|
||||
|
||||
/**
|
||||
* Validates the given string by matching against the pattern, prints an error on failure and exits
|
||||
*
|
||||
|
||||
@@ -382,13 +382,12 @@ exit "$RETVAL"
|
||||
</daemon>
|
||||
<daemon name="powerdns" title="PowerDNS (standalone)">
|
||||
<install><![CDATA[apt-get install pdns-server pdns-backend-mysql]]></install>
|
||||
<file name="/etc/powerdns/pdns.conf" backup="true" chmod="600">
|
||||
<file name="/etc/powerdns/pdns.conf" backup="true" chown="root:pdns" chmod="640">
|
||||
<content><![CDATA[
|
||||
#################################
|
||||
# allow-axfr-ips Allow zonetransfers only to these subnets
|
||||
#
|
||||
allow-axfr-ips=127.0.0.0/8,::1,<NAMESERVERS_IP>
|
||||
# add these entries to the list if any speficied: <AXFRSERVERS>
|
||||
|
||||
#################################
|
||||
# allow-dnsupdate-from A global setting to allow DNS updates from these IP ranges.
|
||||
@@ -907,7 +906,7 @@ include-dir=/etc/powerdns/froxlor/
|
||||
</file>
|
||||
<command><![CDATA[mkdir -p /etc/powerdns/froxlor/]]></command>
|
||||
<file name="/etc/powerdns/froxlor/pdns_froxlor.conf"
|
||||
chown="root:root" chmod="600">
|
||||
chown="root:pdns" chmod="640">
|
||||
<content><![CDATA[
|
||||
# mysql-settings / you need to create the power-dns database for yourself!
|
||||
launch=gmysql
|
||||
@@ -917,6 +916,8 @@ gmysql-dbname=pdns
|
||||
gmysql-user=powerdns
|
||||
gmysql-group=client
|
||||
gmysql-password=
|
||||
#gmysql-ssl-ca-file=
|
||||
#gmysql-ssl-verify-server-certificate=0
|
||||
]]>
|
||||
</content>
|
||||
</file>
|
||||
@@ -925,13 +926,12 @@ gmysql-password=
|
||||
<daemon name="powerdns_bind"
|
||||
title="PowerDNS via bind-backend">
|
||||
<install><![CDATA[apt-get install pdns-server]]></install>
|
||||
<file name="/etc/powerdns/pdns.conf" backup="true" chmod="600">
|
||||
<file name="/etc/powerdns/pdns.conf" backup="true" chown="root:pdns" chmod="640">
|
||||
<content><![CDATA[
|
||||
#################################
|
||||
# allow-axfr-ips Allow zonetransfers only to these subnets
|
||||
#
|
||||
# allow-axfr-ips=127.0.0.0/8,::1,<NAMESERVERS_IP>
|
||||
# add these entries to the list if any speficied: <AXFRSERVERS>
|
||||
|
||||
#################################
|
||||
# allow-dnsupdate-from A global setting to allow DNS updates from these IP ranges.
|
||||
@@ -1451,7 +1451,7 @@ include-dir=/etc/powerdns/froxlor/
|
||||
</file>
|
||||
<command><![CDATA[mkdir -p /etc/powerdns/froxlor/]]></command>
|
||||
<file name="/etc/powerdns/froxlor/pdns_froxlor.conf"
|
||||
chown="root:root" chmod="600">
|
||||
chown="root:pdns" chmod="640">
|
||||
<content><![CDATA[
|
||||
# Bind backend configuration
|
||||
|
||||
@@ -2228,7 +2228,7 @@ debugger_command =
|
||||
# >$config_directory/$process_name.$process_id.log & sleep 5
|
||||
#
|
||||
# Another possibility is to run gdb under a detached screen session.
|
||||
# To attach to the screen sesssion, su root and run "screen -r
|
||||
# To attach to the screen session, su root and run "screen -r
|
||||
# <id_string>" where <id_string> uniquely matches one of the detached
|
||||
# sessions (from "screen -list").
|
||||
#
|
||||
@@ -2642,7 +2642,7 @@ driver = mysql
|
||||
# settings, like: host=sql1.host.org host=sql2.host.org
|
||||
#
|
||||
# pgsql:
|
||||
# For available options, see the PostgreSQL documention for the
|
||||
# For available options, see the PostgreSQL documentation for the
|
||||
# PQconnectdb function of libpq.
|
||||
# Use maxconns=n (default 5) to change how many connections Dovecot can
|
||||
# create to pgsql.
|
||||
@@ -2745,7 +2745,7 @@ user_query = SELECT CONCAT(homedir, maildir) AS home, CONCAT('maildir:', homedir
|
||||
password_query = SELECT username AS user, password_enc AS password, CONCAT(homedir, maildir) AS userdb_home, uid AS userdb_uid, gid AS userdb_gid, CONCAT('maildir:', homedir, maildir) AS userdb_mail, CONCAT('*:storage=', quota, 'M') as userdb_quota_rule FROM mail_users WHERE (username = '%u' OR email = '%u') AND ((imap = 1 AND '%Ls' = 'imap') OR (pop3 = 1 AND '%Ls' = 'pop3') OR ((postfix = 'Y' AND '%Ls' = 'smtp') OR (postfix = 'Y' AND '%Ls' = 'sieve')))
|
||||
|
||||
# Query to get a list of all usernames.
|
||||
#iterate_query = SELECT username AS user FROM users
|
||||
iterate_query = "SELECT username AS user FROM mail_users WHERE (imap = 1 OR pop3 = 1)"
|
||||
]]>
|
||||
</content>
|
||||
</file>
|
||||
@@ -3707,7 +3707,7 @@ protocol sieve {
|
||||
#
|
||||
# If you want UIDL compatibility with other POP3 servers, use:
|
||||
# UW's ipop3d : %08Xv%08Xu
|
||||
# Courier : %f or %v-%u (both might be used simultaneosly)
|
||||
# Courier : %f or %v-%u (both might be used simultaneously)
|
||||
# Cyrus (<= 2.1.3) : %u
|
||||
# Cyrus (>= 2.1.4) : %v.%u
|
||||
# Dovecot v0.99.x : %v.%u
|
||||
@@ -3877,6 +3877,15 @@ plugin {
|
||||
# (Currently only relevant for ManageSieve)
|
||||
#sieve_quota_max_storage = 0
|
||||
}
|
||||
]]>
|
||||
</content>
|
||||
</file>
|
||||
<file name="/etc/dovecot/conf.d/90-quota.conf" chown="root:0"
|
||||
chmod="0644" backup="true">
|
||||
<content><![CDATA[
|
||||
plugin {
|
||||
quota = maildir:User quota
|
||||
}
|
||||
]]>
|
||||
</content>
|
||||
</file>
|
||||
@@ -3965,7 +3974,7 @@ Port 21
|
||||
# PassivePorts 49152 65534
|
||||
|
||||
# If your host was NATted, this option is useful in order to
|
||||
# allow passive tranfers to work. You have to use your public
|
||||
# allow passive transfers to work. You have to use your public
|
||||
# address and opening the passive ports used on your firewall as well.
|
||||
# MasqueradeAddress 1.2.3.4
|
||||
|
||||
@@ -3990,7 +3999,7 @@ Group nogroup
|
||||
# Umask 022 is a good standard umask to prevent new files and dirs
|
||||
# (second parm) from being group and world writable.
|
||||
Umask 022 022
|
||||
# Normally, we want files to be overwriteable.
|
||||
# Normally, we want files to be overwritable.
|
||||
AllowOverwrite on
|
||||
|
||||
# Uncomment this if you are using NIS or LDAP via NSS to retrieve passwords:
|
||||
@@ -4237,7 +4246,7 @@ SQLBackend mysql
|
||||
SQLEngine on
|
||||
SQLAuthenticate on
|
||||
#
|
||||
# Use both a crypted or plaintext password
|
||||
# Use both an encrypted or plaintext password
|
||||
SQLAuthTypes Crypt
|
||||
|
||||
SQLAuthenticate users* groups*
|
||||
@@ -4295,7 +4304,7 @@ TLSVerifyClient off
|
||||
#TLSRequired on
|
||||
|
||||
# Allow SSL/TLS renegotiations when the client requests them, but
|
||||
# do not force the renegotations. Some clients do not support
|
||||
# do not force the renegotiations. Some clients do not support
|
||||
# SSL/TLS renegotiations; when mod_tls forces a renegotiation, these
|
||||
# clients will close the data connection, or there will be a timeout
|
||||
# on an idle data connection.
|
||||
@@ -4536,12 +4545,6 @@ UPLOADGID=
|
||||
</service>
|
||||
<!-- System tools/services -->
|
||||
<service type="system" title="{{lng.admin.configfiles.etc}}">
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
<!-- AWstats -->
|
||||
<daemon name="awstats"
|
||||
title="Awstats (webalizer alternative)">
|
||||
@@ -4595,7 +4598,7 @@ aliases: files
|
||||
chmod="0644">
|
||||
<content><![CDATA[
|
||||
#
|
||||
# Froxlor logrotate snipet
|
||||
# Froxlor logrotate snippet
|
||||
#
|
||||
<CUSTOMER_LOGS>*.log {
|
||||
missingok
|
||||
@@ -4669,6 +4672,12 @@ aliases: files
|
||||
dirty work -->
|
||||
<command><![CDATA[php {{const.install_dir}}scripts/froxlor_master_cronjob.php --force]]></command>
|
||||
</daemon>
|
||||
<!-- Cronjob -->
|
||||
<daemon name="cron" title="Cronjob for froxlor"
|
||||
mandatory="true">
|
||||
<command><![CDATA[/usr/bin/php <BASE_PATH>scripts/froxlor_master_cronjob.php --run-task 99]]></command>
|
||||
<command><![CDATA[{{settings.system.crondreload}}]]></command>
|
||||
</daemon>
|
||||
</service>
|
||||
</services>
|
||||
</distribution>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user