merged with v0.10.33

This commit is contained in:
2022-03-01 12:29:50 +01:00
221 changed files with 16958 additions and 5289 deletions

View File

@@ -1,4 +0,0 @@
codecov:
notify:
require_ci_to_pass: no

View File

@@ -48,7 +48,7 @@ strings in
### New settings and database-layout changnes ### New settings and database-layout changes
If you add new settings or layout changes, please make sure you add these to If you add new settings or layout changes, please make sure you add these to
* `install/froxlor.sql` * `install/froxlor.sql`

View File

@@ -1,6 +1,6 @@
# Bug report vs. support request # Bug report vs. support request
If you're unsure of whether your problem is a bug or a configuration error 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 * or post a thread in our forum at https://forum.froxlor.org
As a rule of thumb: before reporting an issue As a rule of thumb: before reporting an issue

40
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View 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.

View 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
View 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
View 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
View 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
View File

@@ -12,10 +12,11 @@ logs/*
.well-known .well-known
.idea .idea
*.iml *.iml
img/
!templates/Maketank/ !templates/Maketank/
!templates/Froxlor/ !templates/Froxlor/
!templates/Sparkle/ !templates/Sparkle/
!templates/misc/ !templates/misc/
templates/Froxlor/assets/img/logo_custom.png templates/Sparkle/assets/css/custom.css
vendor/ vendor/

View File

@@ -52,13 +52,10 @@ install:
- mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql - mysql -h 127.0.0.1 --protocol=TCP -u root -pfr0xl0r.TravisCI froxlor010 < install/froxlor.sql
script: script:
- ant phpunit - ant phpunit-no-coverage
after_success:
- bash <(curl -s https://codecov.io/bash) -f "build/logs/clover.xml"
notifications: notifications:
irc: "irc.freenode.org#froxlor" irc: "irc.libera.chat#froxlor"
webhooks: webhooks:
urls: urls:
- https://webhooks.gitter.im/e/bdf91d1c3f745e51f796 - https://webhooks.gitter.im/e/bdf91d1c3f745e51f796

View File

@@ -38,7 +38,7 @@ if (AREA == 'admin') {
} }
$success_message = ""; $success_message = "";
$tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor'); $tfa = new \Froxlor\FroxlorTwoFactorAuth('Froxlor ' . Settings::Get('system.hostname'));
// do the delete and then just show a success-message // do the delete and then just show a success-message
if ($action == 'delete') { if ($action == 'delete') {

View File

@@ -1,5 +1,6 @@
[![Build Status](https://travis-ci.com/Froxlor/Froxlor.svg?branch=master)](https://travis-ci.com/Froxlor/Froxlor) [![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mariadb.yml)
[![Gitter](https://badges.gitter.im/Froxlor/community.svg)](https://gitter.im/Froxlor/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge) [![Froxlor-CI](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml/badge.svg?branch=master)](https://github.com/Froxlor/Froxlor/actions/workflows/build-mysql.yml)
[![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.froxlor.org)
# Froxlor # Froxlor
@@ -20,16 +21,20 @@ Developed by experienced server administrators, this panel simplifies the effort
9. Have fun! 9. Have fun!
### Detailed installation ### Detailed installation
https://github.com/Froxlor/Froxlor/wiki/Install-froxlor-from-tarball https://docs.froxlor.org/general/installation/index.html
## Help ## Help
You may find help in the following places: You may find help in the following places:
### Discord
The froxlor community discord server can be found here: https://discord.froxlor.org
### IRC ### IRC
froxlor may be found on freenode.net, channel #froxlor: froxlor may be found on libera.chat, channel #froxlor:
irc://chat.freenode.net/froxlor irc://irc.libera.chat/froxlor
### Forum ### Forum
@@ -37,12 +42,12 @@ The community is located on https://forum.froxlor.org/
### Wiki ### Wiki
More documentation may be found in the froxlor - wiki: More documentation may be found in the froxlor - documentation:
https://github.com/Froxlor/Froxlor/wiki https://docs.froxlor.org/
## License ## License
May be found in COPYING May be found in [COPYING](COPYING)
## Downloads ## Downloads
@@ -51,7 +56,7 @@ https://files.froxlor.org/releases/froxlor-latest.tar.gz [MD5](https://files.fro
### Debian repository ### 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 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 ### 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 apt-get -y install apt-transport-https lsb-release ca-certificates

View File

@@ -77,14 +77,6 @@ return array(
'default' => false, 'default' => false,
'save_method' => 'storeSettingField' '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( 'panel_paging' => array(
'label' => $lng['serversettings']['paging'], 'label' => $lng['serversettings']['paging'],
'settinggroup' => 'panel', 'settinggroup' => 'panel',
@@ -257,7 +249,7 @@ return array(
'extras' => $lng['menue']['extras']['extras'], 'extras' => $lng['menue']['extras']['extras'],
'extras.directoryprotection' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['directoryprotection'], 'extras.directoryprotection' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['directoryprotection'],
'extras.pathoptions' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['pathoptions'], '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'], 'extras.backup' => $lng['menue']['extras']['extras'] . " / " . $lng['menue']['extras']['backup'],
'traffic' => $lng['menue']['traffic']['traffic'], 'traffic' => $lng['menue']['traffic']['traffic'],
'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP", 'traffic.http' => $lng['menue']['traffic']['traffic'] . " / HTTP",
@@ -265,7 +257,71 @@ return array(
'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail" 'traffic.mail' => $lng['menue']['traffic']['traffic'] . " / Mail"
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
) ),
'panel_imprint_url' => array(
'label' => $lng['serversettings']['imprint_url'],
'settinggroup' => 'panel',
'varname' => 'imprint_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
),
'panel_terms_url' => array(
'label' => $lng['serversettings']['terms_url'],
'settinggroup' => 'panel',
'varname' => 'terms_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
),
'panel_privacy_url' => array(
'label' => $lng['serversettings']['privacy_url'],
'settinggroup' => 'panel',
'varname' => 'privacy_url',
'type' => 'string',
'string_type' => 'url',
'string_emptyallowed' => true,
'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'
),
) )
) )
) )

View File

@@ -205,9 +205,21 @@ return array(
'default' => false, 'default' => false,
'cronmodule' => 'froxlor/backup', 'cronmodule' => 'froxlor/backup',
'save_method' => 'storeSettingField' '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'
),
) )
) )
) )
); );

View File

@@ -270,6 +270,28 @@ return array(
'default' => true, 'default' => true,
'save_method' => 'storeSettingField' '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',
'varname' => 'hide_incompatible_settings',
'type' => 'bool',
'default' => false,
'save_method' => 'storeSettingField'
),
) )
) )
) )

View File

@@ -35,7 +35,7 @@ return array(
'settinggroup' => 'system', 'settinggroup' => 'system',
'varname' => 'ssl_protocols', 'varname' => 'ssl_protocols',
'type' => 'option', 'type' => 'option',
'default' => 'TLSv1,TLSv1.2', 'default' => 'TLSv1.2',
'option_mode' => 'multiple', 'option_mode' => 'multiple',
'option_options' => array( 'option_options' => array(
'TLSv1' => 'TLSv1', 'TLSv1' => 'TLSv1',
@@ -122,10 +122,7 @@ return array(
'type' => 'bool', 'type' => 'bool',
'default' => true, 'default' => true,
'save_method' => 'storeSettingField', 'save_method' => 'storeSettingField',
'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1)) && call_user_func(array( 'visible' => \Froxlor\Settings::Get('system.use_ssl') && (\Froxlor\Settings::Get('system.webserver') == "nginx" || (\Froxlor\Settings::Get('system.webserver') == "apache2" && \Froxlor\Settings::Get('system.apache24') == 1))
'\Froxlor\Settings\FroxlorVhostSettings',
'hasVhostContainerEnabled'
), true)
), ),
'system_leenabled' => array( 'system_leenabled' => array(
'label' => $lng['serversettings']['leenabled'], 'label' => $lng['serversettings']['leenabled'],
@@ -136,6 +133,15 @@ return array(
'cronmodule' => 'froxlor/letsencrypt', 'cronmodule' => 'froxlor/letsencrypt',
'save_method' => 'storeSettingField' '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( 'system_letsencryptacmeconf' => array(
'label' => $lng['serversettings']['letsencryptacmeconf'], 'label' => $lng['serversettings']['letsencryptacmeconf'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -145,6 +151,9 @@ return array(
'default' => '/etc/apache2/conf-enabled/acme.conf', 'default' => '/etc/apache2/conf-enabled/acme.conf',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
/**
* currently the only option anyway
*
'system_leapiversion' => array( 'system_leapiversion' => array(
'label' => $lng['serversettings']['leapiversion'], 'label' => $lng['serversettings']['leapiversion'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -157,16 +166,20 @@ return array(
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
*/
'system_letsencryptca' => array( 'system_letsencryptca' => array(
'label' => $lng['serversettings']['letsencryptca'], 'label' => $lng['serversettings']['letsencryptca'],
'settinggroup' => 'system', 'settinggroup' => 'system',
'varname' => 'letsencryptca', 'varname' => 'letsencryptca',
'type' => 'option', 'type' => 'option',
'default' => 'production', 'default' => 'letsencrypt',
'option_mode' => 'one', 'option_mode' => 'one',
'option_options' => array( 'option_options' => array(
'testing' => 'https://acme-staging-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Test)', 'letsencrypt_test' => 'Let\'s Encrypt (Test / Staging)',
'production' => 'https://acme-v0' . \Froxlor\Settings::Get('system.leapiversion') . '.api.letsencrypt.org (Live)' 'letsencrypt' => 'Let\'s Encrypt (Live)',
'buypass_test' => 'Buypass (Test / Staging)',
'buypass' => 'Buypass (Live)',
'zerossl' => 'ZeroSSL (Live)'
), ),
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
@@ -217,11 +230,11 @@ return array(
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'system_disable_le_selfcheck' => array( 'system_disable_le_selfcheck' => array(
'label' => $lng['serversettings']['disable_le_selfcheck'], 'label' => $lng['serversettings']['le_domain_dnscheck'],
'settinggroup' => 'system', 'settinggroup' => 'system',
'varname' => 'disable_le_selfcheck', 'varname' => 'le_domain_dnscheck',
'type' => 'bool', 'type' => 'bool',
'default' => false, 'default' => true,
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
) )
) )

View File

@@ -99,6 +99,19 @@ return array(
'default' => '', 'default' => '',
'save_method' => 'storeSettingField' '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( 'system_dns_createmailentry' => array(
'label' => $lng['serversettings']['mail_also_with_mxservers'], 'label' => $lng['serversettings']['mail_also_with_mxservers'],
'settinggroup' => 'system', 'settinggroup' => 'system',
@@ -132,6 +145,16 @@ return array(
'int_min' => 3600, /* 1 hour */ 'int_min' => 3600, /* 1 hour */
'int_max' => 2147483647, /* integer max */ 'int_max' => 2147483647, /* integer max */
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
),
'system_soaemail' => array(
'label' => $lng['serversettings']['soaemail'],
'settinggroup' => 'system',
'varname' => 'soaemail',
'type' => 'string',
'string_type' => 'mail',
'string_emptyallowed' => true,
'default' => '',
'save_method' => 'storeSettingField'
) )
) )
) )

View File

@@ -39,6 +39,15 @@ return array(
'default' => '/etc/postfix/dkim/', 'default' => '/etc/postfix/dkim/',
'save_method' => 'storeSettingField' 'save_method' => 'storeSettingField'
), ),
'dkim_privkeysuffix' => array(
'label' => $lng['dkim']['privkeysuffix'],
'settinggroup' => 'dkim',
'varname' => 'privkeysuffix',
'type' => 'string',
'string_regexp' => '/^[a-z0-9\._]+$/i',
'default' => '.priv',
'save_method' => 'storeSettingField'
),
'dkim_domains' => array( 'dkim_domains' => array(
'label' => $lng['dkim']['dkim_domains'], 'label' => $lng['dkim']['dkim_domains'],
'settinggroup' => 'dkim', 'settinggroup' => 'dkim',

View File

@@ -82,7 +82,20 @@ return array(
'string_emptyallowed' => true, 'string_emptyallowed' => true,
'default' => '', 'default' => '',
'save_method' => 'storeSettingField' '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')
),
) )
) )
) )

View File

@@ -107,7 +107,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
$count ++; $count ++;
} }
$admincount = $paging->getEntries(); $admincount = $result['count'] . " / " . $paging->getEntries();
eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("admins/admins") . "\";");
} elseif ($action == 'su') { } elseif ($action == 'su') {
@@ -129,7 +129,7 @@ if ($page == 'admins' && $userinfo['change_serversettings'] == '1') {
'userid' => $userinfo['userid'] 'userid' => $userinfo['userid']
)); ));
$s = md5(uniqid(microtime(), 1)); $s = \Froxlor\Froxlor::genSessionId();
$ins_stmt = Database::prepare(" $ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
`hash` = :hash, `userid` = :userid, `ipaddress` = :ip, `hash` = :hash, `userid` = :userid, `ipaddress` = :ip,

View File

@@ -67,6 +67,9 @@ if ($page == 'showinfo') {
$uptime_duration = duration($cache['start_time']); $uptime_duration = duration($cache['start_time']);
$size_vars = bsize($cache['mem_size']); $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 // check for possible empty values that are used in the templates
if (! isset($cache['file_upload_progress'])) { if (! isset($cache['file_upload_progress'])) {
$cache['file_upload_progress'] = $lng['logger']['unknown']; $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); $freemem = bsize($mem_avail) . sprintf(" (%.1f%%)", $mem_avail * 100 / $mem_size);
$usedmem = bsize($mem_used) . sprintf(" (%.1f%%)", $mem_used * 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'])); $hits = $cache['num_hits'] . @sprintf(" (%.1f%%)", $cache['num_hits'] * 100 / $num_hits_and_misses);
$misses = $cache['num_misses'] . @sprintf(" (%.1f%%)", $cache['num_misses'] * 100 / ($cache['num_hits'] + $cache['num_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; $nseg = $freeseg = $fragsize = $freetotal = 0;
for ($i = 0; $i < $mem['num_seg']; $i ++) { for ($i = 0; $i < $mem['num_seg']; $i ++) {
$ptr = 0; $ptr = 0;

View File

@@ -38,13 +38,43 @@ if ($userinfo['change_serversettings'] == '1') {
// try to convert namserver hosts to ip's // try to convert namserver hosts to ip's
$ns_ips = ""; $ns_ips = "";
$known_ns_ips = [];
if (Settings::Get('system.nameservers') != '') { if (Settings::Get('system.nameservers') != '') {
$nameservers = explode(',', Settings::Get('system.nameservers')); $nameservers = explode(',', Settings::Get('system.nameservers'));
foreach ($nameservers as $nameserver) { foreach ($nameservers as $nameserver) {
$nameserver = trim($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); $nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) { // append dot to hostname
$ns_ips .= implode(",", $nameserver_ips); 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'), '<SERVERIP>' => Settings::Get('system.ipaddress'),
'<NAMESERVERS>' => Settings::Get('system.nameservers'), '<NAMESERVERS>' => Settings::Get('system.nameservers'),
'<NAMESERVERS_IP>' => $ns_ips, '<NAMESERVERS_IP>' => $ns_ips,
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'), '<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'), '<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'), '<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),

View File

@@ -150,7 +150,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
$count ++; $count ++;
} }
$customercount = $paging->getEntries(); $customercount = $result['count'] . " / " . $paging->getEntries();
eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("customers/customers") . "\";");
} elseif ($action == 'su' && $id != 0) { } elseif ($action == 'su' && $id != 0) {
try { try {
@@ -178,7 +178,7 @@ if ($page == 'customers' && $userinfo['customers'] != '0') {
'hash' => $s 'hash' => $s
)); ));
$s = md5(uniqid(microtime(), 1)); $s = \Froxlor\Froxlor::genSessionId();
$insert = Database::prepare(" $insert = Database::prepare("
INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET INSERT INTO `" . TABLE_PANEL_SESSIONS . "` SET
`hash` = :hash, `hash` = :hash,

View File

@@ -39,7 +39,7 @@ if ($page == 'domains' || $page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_domains"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_domains");
$fields = array( $fields = array(
'd.domain' => $lng['domains']['domainname'], 'd.domain_ace' => $lng['domains']['domainname'],
'c.name' => $lng['customer']['name'], 'c.name' => $lng['customer']['name'],
'c.firstname' => $lng['customer']['firstname'], 'c.firstname' => $lng['customer']['firstname'],
'c.company' => $lng['customer']['company'], 'c.company' => $lng['customer']['company'],
@@ -80,7 +80,7 @@ if ($page == 'domains' || $page == 'overview') {
$count++; $count++;
} }
$domainscount = $paging->getEntries(); $domainscount = $result['count'] . " / " . $paging->getEntries();
// Display the list // Display the list
eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("domains/domains") . "\";");
@@ -290,9 +290,9 @@ if ($page == 'domains' || $page == 'overview') {
// create serveralias options // create serveralias options
$serveraliasoptions = ""; $serveraliasoptions = "";
$serveraliasoptions .= \Froxlor\UI\HTML::makeoption($lng['domains']['serveraliasoption_wildcard'], '0', '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', '0', 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', '0', 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']['never'], '0', '0', true, true);
$subcanemaildomain .= \Froxlor\UI\HTML::makeoption($lng['admin']['subcanemaildomain']['choosableno'], '1', '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( $customer = Database::pexecute_first($customer_stmt, array(
'customerid' => $result['customerid'] 'customerid' => $result['customerid']
)); ));
$result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer) . ' (' . $customer['loginname'] . ')'; $result['customername'] = \Froxlor\User::getCorrectFullUserDetails($customer);
} }
if ($userinfo['customers_see_all'] == '1') { if ($userinfo['customers_see_all'] == '1') {
@@ -594,6 +594,10 @@ if ($page == 'domains' || $page == 'overview') {
} }
$result = \Froxlor\PhpHelper::htmlentitiesArray($result); $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_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_edit.php';
$domain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_edit_data); $domain_edit_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_edit_data);
@@ -616,7 +620,6 @@ if ($page == 'domains' || $page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$customerid = intval($_POST['customerid']);
$separator = \Froxlor\Validate\Validate::validate($_POST['separator'], 'separator'); $separator = \Froxlor\Validate\Validate::validate($_POST['separator'], 'separator');
$offset = (int) \Froxlor\Validate\Validate::validate($_POST['offset'], 'offset', "/[0-9]/i"); $offset = (int) \Froxlor\Validate\Validate::validate($_POST['offset'], 'offset', "/[0-9]/i");
@@ -625,7 +628,7 @@ if ($page == 'domains' || $page == 'overview') {
$result = array(); $result = array();
try { try {
$bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $customerid); $bulk = new \Froxlor\Bulk\DomainBulkAction($file_name, $userinfo);
$result = $bulk->doImport($separator, $offset); $result = $bulk->doImport($separator, $offset);
} catch (Exception $e) { } catch (Exception $e) {
\Froxlor\UI\Response::standard_error('domain_import_error', $e->getMessage()); \Froxlor\UI\Response::standard_error('domain_import_error', $e->getMessage());
@@ -637,8 +640,8 @@ if ($page == 'domains' || $page == 'overview') {
// update customer/admin counters // update customer/admin counters
\Froxlor\User::updateCounters(false); \Froxlor\User::updateCounters(false);
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
\Froxlor\System\Cronjob::inserttask('4'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
$result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : ''); $result_str = $result['imported'] . ' / ' . $result['all'] . (! empty($result['note']) ? ' (' . $result['note'] . ')' : '');
\Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array( \Froxlor\UI\Response::standard_success('domain_import_successfully', $result_str, array(
@@ -647,19 +650,6 @@ if ($page == 'domains' || $page == 'overview') {
'page' => 'domains' 'page' => 'domains'
)); ));
} else { } else {
$customers = \Froxlor\UI\HTML::makeoption($lng['panel']['please_choose'], 0, 0, true);
$result_customers_stmt = Database::prepare("
SELECT `customerid`, `loginname`, `name`, `firstname`, `company`
FROM `" . TABLE_PANEL_CUSTOMERS . "` " . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = '" . (int) $userinfo['adminid'] . "' ") . " ORDER BY `name` ASC");
$params = array();
if ($userinfo['customers_see_all'] == '0') {
$params['adminid'] = $userinfo['adminid'];
}
Database::pexecute($result_customers_stmt, $params);
while ($row_customer = $result_customers_stmt->fetch(PDO::FETCH_ASSOC)) {
$customers .= \Froxlor\UI\HTML::makeoption(\Froxlor\User::getCorrectFullUserDetails($row_customer) . ' (' . $row_customer['loginname'] . ')', $row_customer['customerid']);
}
$domain_import_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_import.php'; $domain_import_data = include_once dirname(__FILE__) . '/lib/formfields/admin/domains/formfield.domains_import.php';
$domain_import_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_import_data); $domain_import_form = \Froxlor\UI\HtmlForm::genHTMLForm($domain_import_data);

View File

@@ -57,6 +57,12 @@ if (isset($_POST['id'])) {
if ($page == 'overview') { if ($page == 'overview') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "viewed admin_index");
$params = [];
if ($userinfo['customers_see_all'] == '0') {
$params = [
'adminid' => $userinfo['adminid']
];
}
$overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`, $overview_stmt = Database::prepare("SELECT COUNT(*) AS `number_customers`,
SUM(`diskspace_used`) AS `diskspace_used`, SUM(`diskspace_used`) AS `diskspace_used`,
SUM(`mysqls_used`) AS `mysqls_used`, SUM(`mysqls_used`) AS `mysqls_used`,
@@ -68,20 +74,18 @@ if ($page == 'overview') {
SUM(`subdomains_used`) AS `subdomains_used`, SUM(`subdomains_used`) AS `subdomains_used`,
SUM(`traffic_used`) AS `traffic_used` SUM(`traffic_used`) AS `traffic_used`
FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid ")); FROM `" . TABLE_PANEL_CUSTOMERS . "`" . ($userinfo['customers_see_all'] ? '' : " WHERE `adminid` = :adminid "));
$overview = Database::pexecute_first($overview_stmt, array( $overview = Database::pexecute_first($overview_stmt, $params);
'adminid' => $userinfo['adminid']
));
$dec_places = Settings::Get('panel.decimal_places'); $dec_places = Settings::Get('panel.decimal_places');
$overview['traffic_used'] = round($overview['traffic_used'] / (1024 * 1024), $dec_places); $overview['traffic_bytes_used'] = $overview['traffic_used'] * 1024;
$overview['diskspace_used'] = round($overview['diskspace_used'] / 1024, $dec_places); $overview['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($overview['traffic_used'] * 1024, null, 'bi');
$overview['diskspace_bytes_used'] = $overview['diskspace_used'] * 1024;
$overview['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($overview['diskspace_used'] * 1024, null, 'bi');
$number_domains_stmt = Database::prepare(" $number_domains_stmt = Database::prepare("
SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "` SELECT COUNT(*) AS `number_domains` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid")); WHERE `parentdomainid`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :adminid"));
$number_domains = Database::pexecute_first($number_domains_stmt, array( $number_domains = Database::pexecute_first($number_domains_stmt, $params);
'adminid' => $userinfo['adminid']
));
$overview['number_domains'] = $number_domains['number_domains']; $overview['number_domains'] = $number_domains['number_domains'];
@@ -111,11 +115,17 @@ if ($page == 'overview') {
} }
$dec_places = Settings::Get('panel.decimal_places'); $dec_places = Settings::Get('panel.decimal_places');
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, $dec_places); // get everything in bytes for the percentage calculation on the dashboard
$userinfo['diskspace_used'] = round($userinfo['diskspace_used'] / 1024, $dec_places); $userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), $dec_places); $userinfo['diskspace_bytes_used'] = $userinfo['diskspace_used'] * 1024;
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), $dec_places); $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
$userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace_used'] * 1024, null, 'bi');
$userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
$userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'customers domains diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
@@ -183,8 +193,12 @@ if ($page == 'overview') {
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
} }
$new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password'); try {
$new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm'); $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
if ($old_password == '') { if ($old_password == '') {
\Froxlor\UI\Response::standard_error(array( \Froxlor\UI\Response::standard_error(array(

View File

@@ -160,5 +160,14 @@ if ($page == 'ipsandports' || $page == 'overview') {
eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_edit") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("ipsandports/ipsandports_edit") . "\";");
} }
} }
} elseif ($action == 'jqCheckIP') {
$ip = $_POST['ip'] ?? "";
if ((filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) || filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) && filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_RES_RANGE | FILTER_FLAG_NO_PRIV_RANGE) == false) {
// returns notice if private network detected so we can display it
echo json_encode($lng['admin']['ipsandports']['ipnote']);
} else {
echo 0;
}
exit();
} }
} }

View File

@@ -32,10 +32,10 @@ if ($page == 'message') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message'); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'viewed panel_message');
if (isset($_POST['send']) && $_POST['send'] == 'send') { 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'); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to admins');
$result = Database::query('SELECT `name`, `email` FROM `' . TABLE_PANEL_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') { if ($userinfo['customers_see_all'] == '1') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, 'sending messages to ALL customers'); $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 . "`"); $result = Database::query('SELECT `firstname`, `name`, `company`, `email` FROM `' . TABLE_PANEL_CUSTOMERS . "`");
@@ -49,7 +49,7 @@ if ($page == 'message') {
)); ));
} }
} else { } else {
\Froxlor\UI\Response::standard_error('noreceipientsgiven'); \Froxlor\UI\Response::standard_error('norecipientsgiven');
} }
$subject = $_POST['subject']; $subject = $_POST['subject'];
@@ -105,7 +105,7 @@ if ($page == 'message') {
$sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0; $sentitems = isset($_GET['sentitems']) ? (int) $_GET['sentitems'] : 0;
if ($sentitems == 0) { if ($sentitems == 0) {
$successmessage = $lng['message']['noreceipients']; $successmessage = $lng['message']['norecipients'];
} else { } else {
$successmessage = str_replace('%s', $sentitems, $lng['message']['success']); $successmessage = str_replace('%s', $sentitems, $lng['message']['success']);
} }
@@ -116,12 +116,12 @@ if ($page == 'message') {
} }
$action = ''; $action = '';
$receipients = ''; $recipients = '';
if ($userinfo['customers_see_all'] == '1') { 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') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('message/message') . "\";");
} }

View File

@@ -22,7 +22,7 @@ require './lib/init.php';
if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') { if ($action == 'reset' && function_exists('opcache_reset') && $userinfo['change_serversettings'] == '1') {
opcache_reset(); 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( header('Location: ' . $linker->getLink(array(
'section' => 'opcacheinfo', 'section' => 'opcacheinfo',
'page' => 'showinfo' 'page' => 'showinfo'

View File

@@ -66,11 +66,11 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
'page' => $page 'page' => $page
), $_part, $settings_all, $settings_part, $only_enabledisable)) { ), $_part, $settings_all, $settings_part, $only_enabledisable)) {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles due to changed setting"); $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 // 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 // cron.d file
\Froxlor\System\Cronjob::inserttask('99'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
\Froxlor\UI\Response::standard_success('settingssaved', '', array( \Froxlor\UI\Response::standard_success('settingssaved', '', array(
'filename' => $filename, 'filename' => $filename,
@@ -146,12 +146,12 @@ if ($page == 'overview' && $userinfo['change_serversettings'] == '1') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles"); $log->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "rebuild configfiles");
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
\Froxlor\System\Cronjob::inserttask('10'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
// Using nameserver, insert a task which rebuilds the server config // 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 // cron.d file
\Froxlor\System\Cronjob::inserttask('99'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
\Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array( \Froxlor\UI\Response::standard_success('rebuildingconfigs', '', array(
'filename' => 'admin_index.php' 'filename' => 'admin_index.php'

View File

@@ -56,6 +56,26 @@ if ($page == 'overview' || $page == 'customers') {
$maxyears = date("Y") - $minyear['year']; $maxyears = date("Y") - $minyear['year'];
} }
$params = [];
if ($userinfo['customers_see_all'] == '0') {
$params = [
'id' => $userinfo['adminid']
];
}
$customer_name_list_stmt = Database::prepare("
SELECT `customerid`,`company`,`name`,`firstname`
FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
ORDER BY name"
);
$traffic_list_stmt = Database::prepare("
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
FROM `" . TABLE_PANEL_TRAFFIC . "`
WHERE year = :year AND `customerid` = :id
GROUP BY month ORDER BY month"
);
for ($years = 0; $years <= $maxyears; $years ++) { for ($years = 0; $years <= $maxyears; $years ++) {
$overview['year'] = date("Y") - $years; $overview['year'] = date("Y") - $years;
@@ -76,14 +96,7 @@ if ($page == 'overview' || $page == 'customers') {
'dec' => 0 'dec' => 0
); );
$customer_name_list_stmt = Database::prepare(" Database::pexecute($customer_name_list_stmt, $params);
SELECT `customerid`,`company`,`name`,`firstname`
FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `deactivated`='0'" . ($userinfo['customers_see_all'] ? '' : " AND `adminid` = :id") . "
ORDER BY name");
Database::pexecute($customer_name_list_stmt, array(
'id' => $userinfo['adminid']
));
while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) { while ($customer_name = $customer_name_list_stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -104,11 +117,6 @@ if ($page == 'overview' || $page == 'customers') {
'dec' => '-' 'dec' => '-'
); );
$traffic_list_stmt = Database::prepare("
SELECT month, SUM(http+ftp_up+ftp_down+mail)*1024 AS traffic
FROM `" . TABLE_PANEL_TRAFFIC . "`
WHERE year = :year AND `customerid` = :id
GROUP BY month ORDER BY month");
Database::pexecute($traffic_list_stmt, array( Database::pexecute($traffic_list_stmt, array(
'year' => (date("Y") - $years), 'year' => (date("Y") - $years),
'id' => $customer_name['customerid'] 'id' => $customer_name['customerid']

View File

@@ -65,7 +65,7 @@ if ($page == 'overview') {
eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('update/update_end') . "\";");
\Froxlor\User::updateCounters(); \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); @chmod(\Froxlor\Froxlor::getInstallDir() . '/lib/userdata.inc.php', 0440);
$successful_update = true; $successful_update = true;

View File

@@ -1,4 +1,6 @@
<?php <?php
use voku\helper\AntiXSS;
require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/vendor/autoload.php';
require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php'; require \Froxlor\Froxlor::getInstallDir() . '/lib/tables.inc.php';
@@ -30,6 +32,12 @@ if (is_null($decoded_request)) {
json_response(400, "Invalid JSON"); json_response(400, "Invalid JSON");
} }
/**
* check for xss attempts and clean request
*/
$antiXss = new AntiXSS();
$request = $antiXss->xss_clean($request);
// validate content // validate content
try { try {
$decoded_request = stripcslashes_deep($decoded_request); $decoded_request = stripcslashes_deep($decoded_request);

View File

@@ -127,7 +127,7 @@ if ($action == 'delete') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed api::api_keys"); $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 $keys_stmt_query = "SELECT ak.*, c.loginname, a.loginname as adminname
FROM `" . TABLE_API_KEYS . "` ak FROM `" . TABLE_API_KEYS . "` ak
LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid` LEFT JOIN `" . TABLE_PANEL_CUSTOMERS . "` c ON `c`.`customerid` = `ak`.`customerid`

View File

@@ -6,21 +6,20 @@
<property name="pdepend" value="${basedir}/vendor/bin/pdepend" /> <property name="pdepend" value="${basedir}/vendor/bin/pdepend" />
<property name="phpcpd" value="${basedir}/vendor/bin/phpcpd" /> <property name="phpcpd" value="${basedir}/vendor/bin/phpcpd" />
<property name="phpcs" value="${basedir}/vendor/bin/phpcs" /> <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="phploc" value="${basedir}/vendor/bin/phploc" />
<property name="phpmd" value="${basedir}/vendor/bin/phpmd" /> <property name="phpmd" value="${basedir}/vendor/bin/phpmd" />
<property name="phpunit" value="${basedir}/vendor/bin/phpunit" /> <property name="phpunit" value="${basedir}/vendor/bin/phpunit" />
<target name="full-build" <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" /> description="Performs static analysis, runs the tests, and generates project documentation" />
<target name="full-build-parallel" <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" /> description="Performs static analysis (executing the tools in parallel), runs the tests, and generates project documentation" />
<target name="quick-build" <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)" /> description="Performs a lint check and runs the tests (without generating code coverage reports)" />
<target name="static-analysis" <target name="static-analysis"
@@ -49,7 +48,6 @@
<delete dir="${basedir}/build/coverage" /> <delete dir="${basedir}/build/coverage" />
<delete dir="${basedir}/build/logs" /> <delete dir="${basedir}/build/logs" />
<delete dir="${basedir}/build/pdepend" /> <delete dir="${basedir}/build/pdepend" />
<delete dir="${basedir}/build/phpdox" />
<property name="clean.done" value="true" /> <property name="clean.done" value="true" />
</target> </target>
@@ -59,7 +57,6 @@
<mkdir dir="${basedir}/build/coverage" /> <mkdir dir="${basedir}/build/coverage" />
<mkdir dir="${basedir}/build/logs" /> <mkdir dir="${basedir}/build/logs" />
<mkdir dir="${basedir}/build/pdepend" /> <mkdir dir="${basedir}/build/pdepend" />
<mkdir dir="${basedir}/build/phpdox" />
<property name="prepare.done" value="true" /> <property name="prepare.done" value="true" />
</target> </target>
@@ -257,7 +254,7 @@
<target name="phpunit-no-coverage" unless="phpunit.done" <target name="phpunit-no-coverage" unless="phpunit.done"
depends="composer" depends="composer"
description="Run unit tests with PHPUnit (without generating code coverage reports)"> 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"> taskname="phpunit">
<arg value="--configuration" /> <arg value="--configuration" />
<arg path="${basedir}/phpunit.xml" /> <arg path="${basedir}/phpunit.xml" />
@@ -269,18 +266,6 @@
<property name="phpunit.done" value="true" /> <property name="phpunit.done" value="true" />
</target> </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"> <target name="-check-failure">
<fail message="PHPUnit did not finish successfully"> <fail message="PHPUnit did not finish successfully">
<condition> <condition>

View File

@@ -25,12 +25,12 @@
"issues": "https://github.com/Froxlor/Froxlor/issues", "issues": "https://github.com/Froxlor/Froxlor/issues",
"forum": "https://forum.froxlor.org/", "forum": "https://forum.froxlor.org/",
"wiki": "https://github.com/Froxlor/Froxlor/wiki", "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", "source": "https://github.com/Froxlor/Froxlor",
"docs": "https://github.com/Froxlor/Froxlor/wiki" "docs": "https://github.com/Froxlor/Froxlor/wiki"
}, },
"require": { "require": {
"php": ">=7.0", "php": "^7.1 || ^8.0",
"ext-session": "*", "ext-session": "*",
"ext-ctype": "*", "ext-ctype": "*",
"ext-pdo": "*", "ext-pdo": "*",
@@ -43,22 +43,23 @@
"ext-curl": "*", "ext-curl": "*",
"ext-json": "*", "ext-json": "*",
"ext-openssl": "*", "ext-openssl": "*",
"ext-fileinfo": "*",
"phpmailer/phpmailer": "~6.0", "phpmailer/phpmailer": "~6.0",
"monolog/monolog": "^1.24", "monolog/monolog": "^1.24",
"robthree/twofactorauth": "^1.6", "robthree/twofactorauth": "^1.6",
"froxlor/idna-convert-legacy": "^2.1" "froxlor/idna-convert-legacy": "^2.1",
}, "voku/anti-xss": "^4.1"
},
"require-dev": { "require-dev": {
"phpunit/phpunit": "8.4.1", "phpunit/phpunit": "^9",
"php": ">=7.3",
"ext-pcntl": "*", "ext-pcntl": "*",
"phpcompatibility/php-compatibility": "*", "phpcompatibility/php-compatibility": "*",
"squizlabs/php_codesniffer": "*", "squizlabs/php_codesniffer": "*",
"pdepend/pdepend": "^2.5", "pdepend/pdepend": "^2.9",
"sebastian/phpcpd": "^4.1", "sebastian/phpcpd": "^6.0",
"theseer/phpdox": "^0.12.0", "phploc/phploc": "^7.0",
"phploc/phploc": "^5.0", "phpmd/phpmd": "^2.10",
"phpmd/phpmd": "^2.6" "phpunit/php-timer" : "^5"
}, },
"suggest": { "suggest": {
"ext-bcmath": "*", "ext-bcmath": "*",

3170
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -42,7 +42,7 @@ if ($page == 'overview') {
if ($action == '') { if ($action == '') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains"); $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_domains::domains");
$fields = array( $fields = array(
'd.domain' => $lng['domains']['domainname'], 'd.domain_ace' => $lng['domains']['domainname'],
'd.aliasdomain' => $lng['domains']['aliasdomain'] 'd.aliasdomain' => $lng['domains']['aliasdomain']
); );
try { try {

View File

@@ -19,7 +19,6 @@
define('AREA', 'customer'); define('AREA', 'customer');
require './lib/init.php'; require './lib/init.php';
use Froxlor\Api\Commands\SubDomains;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Api\Commands\Emails as Emails; use Froxlor\Api\Commands\Emails as Emails;
@@ -44,7 +43,7 @@ if ($page == 'overview') {
if ($action == '') { if ($action == '') {
$log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails"); $log->logAction(\Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "viewed customer_email::emails");
$fields = array( $fields = array(
'd.domain' => $lng['domains']['domainname'], 'd.domain_ace' => $lng['domains']['domainname'],
'm.email_full' => $lng['emails']['emailaddress'], 'm.email_full' => $lng['emails']['emailaddress'],
'm.destination' => $lng['emails']['forwarders'] 'm.destination' => $lng['emails']['forwarders']
); );
@@ -76,7 +75,7 @@ if ($page == 'overview') {
$emails[$row['domain']][$row['email_full']] = $row; $emails[$row['domain']][$row['email_full']] = $row;
} }
if ($paging->sortfield == 'd.domain' && $paging->sortorder == 'desc') { if ($paging->sortfield == 'd.domain_ace' && $paging->sortorder == 'desc') {
krsort($emails); krsort($emails);
} else { } else {
ksort($emails); ksort($emails);
@@ -129,16 +128,15 @@ if ($page == 'overview') {
} }
} }
$json_result = SubDomains::getLocal($userinfo, [ $result_stmt = Database::prepare("
'sql_search' => [ SELECT COUNT(`id`) as emaildomains
'd.isemaildomain' => [ FROM `" . TABLE_PANEL_DOMAINS . "`
'value' => 1, WHERE `customerid`= :cid AND `isemaildomain` = '1'
'op' => '=' ");
] $result2 = Database::pexecute_first($result_stmt, array(
] "cid" => $userinfo['customerid']
])->listing(); ));
$result = json_decode($json_result, true)['data']; $emaildomains_count = $result2['emaildomains'];
$emaildomains_count = $result['count'];
eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate("email/emails") . "\";");
} elseif ($action == 'delete' && $id != 0) { } elseif ($action == 'delete' && $id != 0) {
@@ -155,7 +153,8 @@ if ($page == 'overview') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
try { try {
Emails::getLocal($userinfo, array( Emails::getLocal($userinfo, array(
'id' => $id 'id' => $id,
'delete_userfiles' => ($_POST['delete_userfiles'] ?? 0)
))->delete(); ))->delete();
} catch (Exception $e) { } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage()); \Froxlor\UI\Response::dynamic_error($e->getMessage());
@@ -196,7 +195,7 @@ if ($page == 'overview') {
$result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "` $result_stmt = Database::prepare("SELECT `id`, `domain`, `customerid` FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid`= :cid WHERE `customerid`= :cid
AND `isemaildomain`='1' AND `isemaildomain`='1'
ORDER BY `domain` ASC"); ORDER BY `domain_ace` ASC");
Database::pexecute($result_stmt, array( Database::pexecute($result_stmt, array(
"cid" => $userinfo['customerid'] "cid" => $userinfo['customerid']
)); ));

View File

@@ -93,22 +93,30 @@ if ($page == 'overview') {
'cid' => $userinfo['customerid'] 'cid' => $userinfo['customerid']
)); ));
if ($usages) // get everything in bytes for the percentage calculation on the dashboard
{ $userinfo['diskspace_bytes'] = ($userinfo['diskspace'] > -1) ? $userinfo['diskspace'] * 1024 : -1;
$userinfo['diskspace_used'] = round($usages['webspace'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['traffic_bytes'] = ($userinfo['traffic'] > -1) ? $userinfo['traffic'] * 1024 : - 1;
$userinfo['mailspace_used'] = round($usages['mail'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['traffic_bytes_used'] = $userinfo['traffic_used'] * 1024;
$userinfo['dbspace_used'] = round($usages['mysql'] / 1024, Settings::Get('panel.decimal_places'));
$userinfo['total_used'] = round(($usages['webspace'] + $usages['mail'] + $usages['mysql']) / 1024, Settings::Get('panel.decimal_places')); if ($usages) {
$userinfo['diskspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['webspace'] * 1024, null, 'bi');
$userinfo['mailspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mail'] * 1024, null, 'bi');
$userinfo['dbspace_used'] = \Froxlor\PhpHelper::sizeReadable($usages['mysql'] * 1024, null, 'bi');
$userinfo['total_used'] = \Froxlor\PhpHelper::sizeReadable(($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024, null, 'bi');
$userinfo['diskspace_bytes_used'] = $usages['webspace'] * 1024;
$userinfo['total_bytes_used'] = ($usages['webspace'] + $usages['mail'] + $usages['mysql']) * 1024;
} else { } else {
$userinfo['diskspace_used'] = 0; $userinfo['diskspace_used'] = 0;
$userinfo['mailspace_used'] = 0; $userinfo['mailspace_used'] = 0;
$userinfo['dbspace_used'] = 0; $userinfo['dbspace_used'] = 0;
$userinfo['total_used'] = 0; $userinfo['total_used'] = 0;
$userinfo['diskspace_bytes_used'] = 0;
$userinfo['total_bytes_used'] = 0;
} }
$userinfo['diskspace'] = round($userinfo['diskspace'] / 1024, Settings::Get('panel.decimal_places')); $userinfo['diskspace'] = ($userinfo['diskspace'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['diskspace'] * 1024, null, 'bi') : - 1;
$userinfo['traffic'] = round($userinfo['traffic'] / (1024 * 1024), Settings::Get('panel.decimal_places')); $userinfo['traffic'] = ($userinfo['traffic'] > -1) ? \Froxlor\PhpHelper::sizeReadable($userinfo['traffic'] * 1024, null, 'bi') : - 1;
$userinfo['traffic_used'] = round($userinfo['traffic_used'] / (1024 * 1024), Settings::Get('panel.decimal_places')); $userinfo['traffic_used'] = \Froxlor\PhpHelper::sizeReadable($userinfo['traffic_used'] * 1024, null, 'bi');
$userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace traffic mysqls emails email_accounts email_forwarders email_quota ftps subdomains'); $userinfo = \Froxlor\PhpHelper::strReplaceArray('-1', $lng['customer']['unlimited'], $userinfo, 'diskspace diskspace_bytes traffic traffic_bytes mysqls emails email_accounts email_forwarders email_quota ftps subdomains');
$userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : ''; $userinfo['custom_notes'] = ($userinfo['custom_notes'] != '') ? nl2br($userinfo['custom_notes']) : '';
@@ -123,19 +131,25 @@ if ($page == 'overview') {
if ($userinfo['perlenabled'] == '1') if ($userinfo['perlenabled'] == '1')
$se[] = "Perl/CGI"; $se[] = "Perl/CGI";
if ($userinfo['api_allowed'] == '1') if ($userinfo['api_allowed'] == '1')
$se[] = '<a href="customer_index.php?s='.$s.'&page=apikeys">API</a>'; $se[] = '<a href="customer_index.php?s=' . $s . '&page=apikeys">API</a>';
$services_enabled = implode(", ", $se); $services_enabled = implode(", ", $se);
eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('index/index') . "\";");
} elseif ($page == 'change_password') { } elseif ($page == 'change_password') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password'); $old_password = \Froxlor\Validate\Validate::validate($_POST['old_password'], 'old password');
if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) { if (! \Froxlor\System\Crypt::validatePasswordLogin($userinfo, $old_password, TABLE_PANEL_CUSTOMERS, 'customerid')) {
\Froxlor\UI\Response::standard_error('oldpasswordnotcorrect'); \Froxlor\UI\Response::standard_error('oldpasswordnotcorrect');
} }
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); try {
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm'); $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password');
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
if ($old_password == '') { if ($old_password == '') {
\Froxlor\UI\Response::standard_error(array( \Froxlor\UI\Response::standard_error(array(

View File

@@ -85,10 +85,12 @@ if ($page == 'overview') {
$mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES $mbdata_stmt = Database::prepare("SELECT SUM(data_length + index_length) as MB FROM information_schema.TABLES
WHERE table_schema = :table_schema WHERE table_schema = :table_schema
GROUP BY table_schema"); GROUP BY table_schema");
Database::pexecute($mbdata_stmt, array( $mbdata = Database::pexecute_first($mbdata_stmt, array(
"table_schema" => $row['databasename'] "table_schema" => $row['databasename']
)); ));
$mbdata = $mbdata_stmt->fetch(PDO::FETCH_ASSOC); if (!$mbdata) {
$mbdata = array('MB' => 0);
}
$row['size'] = \Froxlor\PhpHelper::sizeReadable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s'); $row['size'] = \Froxlor\PhpHelper::sizeReadable($mbdata['MB'], 'GiB', 'bi', '%01.' . (int) Settings::Get('panel.decimal_places') . 'f %s');
eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";"); eval("\$mysqls.=\"" . \Froxlor\UI\Template::getTemplate('mysql/mysqls_database') . "\";");
$count ++; $count ++;

View File

@@ -86,22 +86,18 @@ if (! is_null($month) && ! is_null($year)) {
if (extension_loaded('bcmath')) { if (extension_loaded('bcmath')) {
$traf['ftptext'] = bcdiv($row['ftp_up'], 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($row['ftp_down'], 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; $traf['ftptext'] = bcdiv($row['ftp_up'], 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($row['ftp_down'], 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = bcdiv($ftp, 1024, Settings::Get('panel.decimal_places')); $traf['ftp'] = bcdiv($ftp, 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = bcdiv($traf['byte'], 1024, Settings::Get('panel.decimal_places'));
} else { } else {
$traf['ftptext'] = round($row['ftp_up'] / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($row['ftp_down'] / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; $traf['ftptext'] = round($row['ftp_up'] / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($row['ftp_down'] / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)"; $traf['ftp'] = round($ftp / 1024, Settings::Get('panel.decimal_places'));
$traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['http'] = round($http, Settings::Get('panel.decimal_places'));
$traf['ftp'] = round($ftp, Settings::Get('panel.decimal_places'));
$traf['mail'] = round($mail, Settings::Get('panel.decimal_places'));
$traf['byte'] = round($traf['byte'] / 1024, Settings::Get('panel.decimal_places'));
} }
getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)");
getReadableTraffic($traf,'http', $http, 1024);
getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)");
getReadableTraffic($traf,'mail', $mail, 1024);
getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024));
eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_month') . "\";"); eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_month') . "\";");
$show = $lng['traffic']['months'][intval($row['month'])] . ' ' . $row['year']; $show = $lng['traffic']['months'][intval($row['month'])] . ' ' . $row['year'];
} }
@@ -142,22 +138,18 @@ if (! is_null($month) && ! is_null($year)) {
if (extension_loaded('bcmath')) { if (extension_loaded('bcmath')) {
$traf['ftptext'] = bcdiv($ftp_up, 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($ftp_down, 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; $traf['ftptext'] = bcdiv($ftp_up, 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . bcdiv($ftp_down, 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = bcdiv(($ftp_up + $ftp_down), 1024, Settings::Get('panel.decimal_places')); $traf['ftp'] = bcdiv(($ftp_up + $ftp_down), 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = bcdiv($http, 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = bcdiv($mail, 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = bcdiv($traf['byte'], 1024 * 1024, Settings::Get('panel.decimal_places'));
} else { } else {
$traf['ftptext'] = round($ftp_up / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($ftp_down / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)"; $traf['ftptext'] = round($ftp_up / 1024, Settings::Get('panel.decimal_places')) . " MiB up/ " . round($ftp_down / 1024, Settings::Get('panel.decimal_places')) . " MiB down (FTP)";
$traf['httptext'] = round($http / 1024, Settings::Get('panel.decimal_places')) . " MiB (HTTP)";
$traf['mailtext'] = round($mail / 1024, Settings::Get('panel.decimal_places')) . " MiB (Mail)";
$traf['ftp'] = round(($ftp_up + $ftp_down) / 1024, Settings::Get('panel.decimal_places')); $traf['ftp'] = round(($ftp_up + $ftp_down) / 1024, Settings::Get('panel.decimal_places'));
$traf['http'] = round($http / 1024, Settings::Get('panel.decimal_places'));
$traf['mail'] = round($mail / 1024, Settings::Get('panel.decimal_places'));
$traf['byte'] = round($traf['byte'] / (1024 * 1024), Settings::Get('panel.decimal_places'));
} }
getReadableTraffic($traf,'httptext', $http, 1024, "MiB (HTTP)");
getReadableTraffic($traf,'http', $http, 1024);
getReadableTraffic($traf,'mailtext', $mail, 1024, "MiB (Mail)");
getReadableTraffic($traf,'mail', $mail, 1024);
getReadableTraffic($traf,'byte', $traf['byte'], (1024 * 1024));
eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_traffic') . "\";"); eval("\$traffic.=\"" . \Froxlor\UI\Template::getTemplate('traffic/traffic_traffic') . "\";");
} }
@@ -167,3 +159,12 @@ if (! is_null($month) && ! is_null($year)) {
eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic') . "\";"); eval("echo \"" . \Froxlor\UI\Template::getTemplate('traffic/traffic') . "\";");
} }
function getReadableTraffic(&$traf, $index, $value, $divisor, $desc = "")
{
if (extension_loaded('bcmath')) {
$traf[$index] = bcdiv($value, $divisor,Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : "");
} else {
$traf[$index] = round($value / $divisor, Settings::Get('panel.decimal_places')).(!empty($desc) ? " ".$desc : "");
}
}

View File

@@ -19,7 +19,6 @@ if (! defined('AREA')) {
* *
*/ */
use Froxlor\Database\Database;
use Froxlor\Api\Commands\DomainZones as DomainZones; use Froxlor\Api\Commands\DomainZones as DomainZones;
// This file is being included in admin_domains and customer_domains // This file is being included in admin_domains and customer_domains
@@ -36,18 +35,6 @@ $ttl = isset($_POST['record']['ttl']) ? (int) $_POST['record']['ttl'] : 18000;
// get domain-name // get domain-name
$domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo); $domain = \Froxlor\Dns\Dns::getAllowedDomainEntry($domain_id, AREA, $userinfo);
// select all entries
try {
// get list
$json_result = DomainZones::getLocal($userinfo, [
'id' => $domain_id
])->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$dom_entries = $result['list'];
$errors = ""; $errors = "";
$success_message = ""; $success_message = "";
@@ -63,8 +50,9 @@ if ($action == 'add_record' && ! empty($_POST)) {
'ttl' => $ttl 'ttl' => $ttl
))->add(); ))->add();
$success_message = $lng['success']['dns_record_added']; $success_message = $lng['success']['dns_record_added'];
$record = $prio = $content = "";
} catch (Exception $e) { } catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage()); $errors = str_replace("\n", "<br>", $e->getMessage());
} }
} elseif ($action == 'delete') { } elseif ($action == 'delete') {
// remove entry // remove entry
@@ -75,26 +63,26 @@ if ($action == 'add_record' && ! empty($_POST)) {
'entry_id' => $entry_id, 'entry_id' => $entry_id,
'id' => $domain_id 'id' => $domain_id
))->delete(); ))->delete();
// success message (inline)
$success_message = $lng['success']['dns_record_deleted'];
} catch (Exception $e) { } catch (Exception $e) {
$errors = str_replace("\n", "<br>", $e->getMessage()); $errors = str_replace("\n", "<br>", $e->getMessage());
} }
if (empty($errors)) {
// remove deleted entry from internal data array (no reread of DB necessary)
$_t = $dom_entries;
foreach ($_t as $idx => $entry) {
if ($entry['id'] == $entry_id) {
unset($dom_entries[$idx]);
break;
}
}
unset($_t);
// success message (inline)
$success_message = $lng['success']['dns_record_deleted'];
}
} }
} }
// select all entries
try {
// get list
$json_result = DomainZones::getLocal($userinfo, [
'id' => $domain_id
])->listing();
} catch (Exception $e) {
\Froxlor\UI\Response::dynamic_error($e->getMessage());
}
$result = json_decode($json_result, true)['data'];
$dom_entries = $result['list'];
// show editor // show editor
$record_list = ""; $record_list = "";
$existing_entries = ""; $existing_entries = "";

View File

@@ -28,6 +28,12 @@ if ($action == '') {
} }
if (session_status() == PHP_SESSION_NONE) { 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(); session_start();
} }
@@ -114,7 +120,7 @@ if ($action == '2fa_entercode') {
)); ));
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row['customer'] == $loginname) { if ($row && $row['customer'] == $loginname) {
$table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $table = "`" . TABLE_PANEL_CUSTOMERS . "`";
$uid = 'customerid'; $uid = 'customerid';
$adminsession = '0'; $adminsession = '0';
@@ -142,7 +148,7 @@ if ($action == '2fa_entercode') {
"loginname" => $loginname "loginname" => $loginname
)); ));
$row3 = $stmt->fetch(PDO::FETCH_ASSOC); $row3 = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row3['customer'] == $loginname) { if ($row3 && $row3['customer'] == $loginname) {
$table = "`" . TABLE_PANEL_CUSTOMERS . "`"; $table = "`" . TABLE_PANEL_CUSTOMERS . "`";
$uid = 'customerid'; $uid = 'customerid';
$adminsession = '0'; $adminsession = '0';
@@ -181,7 +187,7 @@ if ($action == '2fa_entercode') {
$row = $stmt->fetch(PDO::FETCH_ASSOC); $row = $stmt->fetch(PDO::FETCH_ASSOC);
} }
if ($row['admin'] == $loginname) { if ($row && $row['admin'] == $loginname) {
$table = "`" . TABLE_PANEL_ADMINS . "`"; $table = "`" . TABLE_PANEL_ADMINS . "`";
$uid = 'adminid'; $uid = 'adminid';
$adminsession = '1'; $adminsession = '1';
@@ -372,6 +378,8 @@ if ($action == '2fa_entercode') {
$lastscript = ""; $lastscript = "";
if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") { if (isset($_REQUEST['script']) && $_REQUEST['script'] != "") {
$lastscript = $_REQUEST['script']; $lastscript = $_REQUEST['script'];
$lastscript = str_replace("..", "", $lastscript);
$lastscript = htmlspecialchars($lastscript, ENT_QUOTES);
if (! file_exists(__DIR__ . "/" . $lastscript)) { if (! file_exists(__DIR__ . "/" . $lastscript)) {
$lastscript = ""; $lastscript = "";
@@ -393,7 +401,7 @@ if ($action == 'forgotpwd') {
if (isset($_POST['send']) && $_POST['send'] == 'send') { if (isset($_POST['send']) && $_POST['send'] == 'send') {
$loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname'); $loginname = \Froxlor\Validate\Validate::validate($_POST['loginname'], 'loginname');
$email = \Froxlor\Validate\Validate::validateEmail($_POST['loginemail'], 'email'); $email = \Froxlor\Validate\Validate::validateEmail($_POST['loginemail'], 'email');
$result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "` $result_stmt = Database::prepare("SELECT `adminid`, `customerid`, `customernumber`, `firstname`, `name`, `company`, `email`, `loginname`, `def_language`, `deactivated` FROM `" . TABLE_PANEL_CUSTOMERS . "`
WHERE `loginname`= :loginname WHERE `loginname`= :loginname
AND `email`= :email"); AND `email`= :email");
Database::pexecute($result_stmt, array( Database::pexecute($result_stmt, array(
@@ -481,6 +489,10 @@ if ($action == 'forgotpwd') {
$replace_arr = array( $replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user), 'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($user),
'NAME' => $user['name'],
'FIRSTNAME' => $user['firstname'] ?? "",
'COMPANY' => $user['company'] ?? "",
'CUSTOMER_NO' => $user['customernumber'] ?? 0,
'USERNAME' => $loginname, 'USERNAME' => $loginname,
'LINK' => $activationlink 'LINK' => $activationlink
); );
@@ -598,21 +610,18 @@ if ($action == 'resetpwd') {
)); ));
if ($result !== false) { if ($result !== false) {
if ($result['admin'] == 1) { try {
$new_password = \Froxlor\Validate\Validate::validate($_POST['new_password'], 'new password'); $new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], true);
$new_password_confirm = \Froxlor\Validate\Validate::validate($_POST['new_password_confirm'], 'new password confirm'); $new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], true);
} else { } catch (Exception $e) {
$new_password = \Froxlor\System\Crypt::validatePassword($_POST['new_password'], 'new password'); $message = $e->getMessage();
$new_password_confirm = \Froxlor\System\Crypt::validatePassword($_POST['new_password_confirm'], 'new password confirm');
} }
if ($new_password == '') { if (empty($message) && (empty($new_password) || $new_password != $new_password_confirm)) {
$message = $new_password; $message = $lng['error']['newpasswordconfirmerror'];
} elseif ($new_password_confirm == '') { }
$message = $new_password_confirm;
} elseif ($new_password != $new_password_confirm) { if (empty($message)) {
$message = $new_password . " != " . $new_password_confirm;
} else {
// Update user password // Update user password
if ($result['admin'] == 1) { if ($result['admin'] == 1) {
$stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "` $stmt = Database::prepare("UPDATE `" . TABLE_PANEL_ADMINS . "`
@@ -668,7 +677,7 @@ function finishLogin($userinfo)
global $version, $dbversion, $remote_addr, $http_user_agent, $languages; global $version, $dbversion, $remote_addr, $http_user_agent, $languages;
if (isset($userinfo['userid']) && $userinfo['userid'] != '') { if (isset($userinfo['userid']) && $userinfo['userid'] != '') {
$s = md5(uniqid(microtime(), 1)); $s = \Froxlor\Froxlor::genSessionId();
if (isset($_POST['language'])) { if (isset($_POST['language'])) {
$language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language'); $language = \Froxlor\Validate\Validate::validate($_POST['language'], 'language');

View File

@@ -15,10 +15,10 @@ CREATE TABLE `ftp_groups` (
DROP TABLE IF EXISTS `ftp_users`; DROP TABLE IF EXISTS `ftp_users`;
CREATE TABLE `ftp_users` ( CREATE TABLE `ftp_users` (
`id` int(20) NOT NULL auto_increment, `id` int(20) NOT NULL auto_increment,
`username` varchar(255) NOT NULL default '', `username` varchar(255) NOT NULL,
`uid` int(5) NOT NULL default '0', `uid` int(5) NOT NULL default '0',
`gid` int(5) NOT NULL default '0', `gid` int(5) NOT NULL default '0',
`password` varchar(128) NOT NULL default '', `password` varchar(128) NOT NULL,
`homedir` varchar(255) NOT NULL default '', `homedir` varchar(255) NOT NULL default '',
`shell` varchar(255) NOT NULL default '/bin/false', `shell` varchar(255) NOT NULL default '/bin/false',
`login_enabled` enum('N','Y') NOT NULL default 'N', `login_enabled` enum('N','Y') NOT NULL default 'N',
@@ -71,6 +71,7 @@ CREATE TABLE `mail_virtual` (
`customerid` int(11) NOT NULL default '0', `customerid` int(11) NOT NULL default '0',
`popaccountid` int(11) NOT NULL default '0', `popaccountid` int(11) NOT NULL default '0',
`iscatchall` tinyint(1) unsigned NOT NULL default '0', `iscatchall` tinyint(1) unsigned NOT NULL default '0',
`description` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `email` (`email`) KEY `email` (`email`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
@@ -84,14 +85,14 @@ CREATE TABLE `panel_activation` (
`creation` int(11) unsigned NOT NULL default '0', `creation` int(11) unsigned NOT NULL default '0',
`activationcode` varchar(50) default NULL, `activationcode` varchar(50) default NULL,
PRIMARY KEY (id) PRIMARY KEY (id)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_admins`; DROP TABLE IF EXISTS `panel_admins`;
CREATE TABLE `panel_admins` ( CREATE TABLE `panel_admins` (
`adminid` int(11) unsigned NOT NULL auto_increment, `adminid` int(11) unsigned NOT NULL auto_increment,
`loginname` varchar(50) NOT NULL default '', `loginname` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL default '', `password` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL default '', `name` varchar(255) NOT NULL default '',
`email` varchar(255) NOT NULL default '', `email` varchar(255) NOT NULL default '',
`def_language` varchar(100) NOT NULL default '', `def_language` varchar(100) NOT NULL default '',
@@ -142,7 +143,7 @@ CREATE TABLE `panel_admins` (
DROP TABLE IF EXISTS `panel_customers`; DROP TABLE IF EXISTS `panel_customers`;
CREATE TABLE `panel_customers` ( CREATE TABLE `panel_customers` (
`customerid` int(11) unsigned NOT NULL auto_increment, `customerid` int(11) unsigned NOT NULL auto_increment,
`loginname` varchar(50) NOT NULL default '', `loginname` varchar(50) NOT NULL,
`password` varchar(255) NOT NULL default '', `password` varchar(255) NOT NULL default '',
`adminid` int(11) unsigned NOT NULL default '0', `adminid` int(11) unsigned NOT NULL default '0',
`name` varchar(255) NOT NULL default '', `name` varchar(255) NOT NULL default '',
@@ -223,7 +224,8 @@ CREATE TABLE `panel_databases` (
DROP TABLE IF EXISTS `panel_domains`; DROP TABLE IF EXISTS `panel_domains`;
CREATE TABLE `panel_domains` ( CREATE TABLE `panel_domains` (
`id` int(11) unsigned NOT NULL auto_increment, `id` int(11) unsigned NOT NULL auto_increment,
`domain` varchar(255) NOT NULL default '', `domain` varchar(255) NOT NULL,
`domain_ace` varchar(255) NOT NULL default '',
`adminid` int(11) unsigned NOT NULL default '0', `adminid` int(11) unsigned NOT NULL default '0',
`customerid` int(11) unsigned NOT NULL default '0', `customerid` int(11) unsigned NOT NULL default '0',
`aliasdomain` int(11) unsigned NULL, `aliasdomain` int(11) unsigned NULL,
@@ -268,12 +270,13 @@ CREATE TABLE `panel_domains` (
`writeaccesslog` tinyint(1) DEFAULT '1', `writeaccesslog` tinyint(1) DEFAULT '1',
`writeerrorlog` tinyint(1) DEFAULT '1', `writeerrorlog` tinyint(1) DEFAULT '1',
`override_tls` tinyint(1) DEFAULT '0', `override_tls` tinyint(1) DEFAULT '0',
`ssl_protocols` text, `ssl_protocols` varchar(255) NOT NULL DEFAULT '',
`ssl_cipher_list` text, `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '',
`tlsv13_cipher_list` text, `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '',
`ssl_enabled` tinyint(1) DEFAULT '1', `ssl_enabled` tinyint(1) DEFAULT '1',
`ssl_honorcipherorder` tinyint(1) DEFAULT '0', `ssl_honorcipherorder` tinyint(1) DEFAULT '0',
`ssl_sessiontickets` tinyint(1) DEFAULT '1', `ssl_sessiontickets` tinyint(1) DEFAULT '1',
`description` varchar(255) NOT NULL DEFAULT '',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `customerid` (`customerid`), KEY `customerid` (`customerid`),
KEY `parentdomain` (`parentdomainid`), KEY `parentdomain` (`parentdomainid`),
@@ -285,7 +288,7 @@ CREATE TABLE `panel_domains` (
DROP TABLE IF EXISTS `panel_ipsandports`; DROP TABLE IF EXISTS `panel_ipsandports`;
CREATE TABLE `panel_ipsandports` ( CREATE TABLE `panel_ipsandports` (
`id` int(11) unsigned NOT NULL auto_increment, `id` int(11) unsigned NOT NULL auto_increment,
`ip` varchar(39) NOT NULL default '', `ip` varchar(39) NOT NULL,
`port` int(5) NOT NULL default '80', `port` int(5) NOT NULL default '80',
`listen_statement` tinyint(1) NOT NULL default '0', `listen_statement` tinyint(1) NOT NULL default '0',
`namevirtualhost_statement` tinyint(1) NOT NULL default '0', `namevirtualhost_statement` tinyint(1) NOT NULL default '0',
@@ -386,6 +389,7 @@ INSERT INTO `panel_settings` (`settinggroup`, `varname`, `value`) VALUES
('dkim', 'dkim_domains', 'domains'), ('dkim', 'dkim_domains', 'domains'),
('dkim', 'dkim_dkimkeys', 'dkim-keys.conf'), ('dkim', 'dkim_dkimkeys', 'dkim-keys.conf'),
('dkim', 'dkimrestart_command', '/etc/init.d/dkim-filter restart'), ('dkim', 'dkimrestart_command', '/etc/init.d/dkim-filter restart'),
('dkim', 'privkeysuffix', '.priv'),
('admin', 'show_news_feed', '0'), ('admin', 'show_news_feed', '0'),
('admin', 'show_version_login', '0'), ('admin', 'show_version_login', '0'),
('admin', 'show_version_footer', '0'), ('admin', 'show_version_footer', '0'),
@@ -491,7 +495,6 @@ opcache.load_comments
opcache.revalidate_path opcache.revalidate_path
opcache.save_comments opcache.save_comments
opcache.use_cwd opcache.use_cwd
opcache.validate_timestamps
opcache.fast_shutdown'), opcache.fast_shutdown'),
('phpfpm', 'ini_admin_values', 'cgi.redirect_status_env ('phpfpm', 'ini_admin_values', 'cgi.redirect_status_env
date.timezone date.timezone
@@ -515,7 +518,8 @@ opcache.restrict_api
opcache.revalidate_freq opcache.revalidate_freq
opcache.max_accelerated_files opcache.max_accelerated_files
opcache.memory_consumption opcache.memory_consumption
opcache.interned_strings_buffer'), opcache.interned_strings_buffer
opcache.validate_timestamps'),
('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'), ('nginx', 'fastcgiparams', '/etc/nginx/fastcgi_params'),
('system', 'lastaccountnumber', '0'), ('system', 'lastaccountnumber', '0'),
('system', 'lastguid', '9999'), ('system', 'lastguid', '9999'),
@@ -528,7 +532,7 @@ opcache.interned_strings_buffer'),
('system', 'vmail_gid', '2000'), ('system', 'vmail_gid', '2000'),
('system', 'vmail_homedir', '/var/customers/mail/'), ('system', 'vmail_homedir', '/var/customers/mail/'),
('system', 'vmail_maildirname', 'Maildir'), ('system', 'vmail_maildirname', 'Maildir'),
('system', 'bind_enable', '1'), ('system', 'bind_enable', '0'),
('system', 'bindconf_directory', '/etc/bind/'), ('system', 'bindconf_directory', '/etc/bind/'),
('system', 'bindreload_command', '/etc/init.d/bind9 reload'), ('system', 'bindreload_command', '/etc/init.d/bind9 reload'),
('system', 'hostname', 'SERVERNAME'), ('system', 'hostname', 'SERVERNAME'),
@@ -553,6 +557,7 @@ opcache.interned_strings_buffer'),
('system', 'ssl_cert_file', '/etc/apache2/apache2.pem'), ('system', 'ssl_cert_file', '/etc/apache2/apache2.pem'),
('system', 'use_ssl', '0'), ('system', 'use_ssl', '0'),
('system', 'default_vhostconf', ''), ('system', 'default_vhostconf', ''),
('system', 'default_sslvhostconf', ''),
('system', 'mail_quota_enabled', '0'), ('system', 'mail_quota_enabled', '0'),
('system', 'mail_quota', '100'), ('system', 'mail_quota', '100'),
('system', 'webalizer_enabled', '1'), ('system', 'webalizer_enabled', '1'),
@@ -606,6 +611,7 @@ opcache.interned_strings_buffer'),
('system', 'documentroot_use_default_value', '0'), ('system', 'documentroot_use_default_value', '0'),
('system', 'passwordcryptfunc', '3'), ('system', 'passwordcryptfunc', '3'),
('system', 'axfrservers', ''), ('system', 'axfrservers', ''),
('system', 'powerdns_mode', 'Native'),
('system', 'customer_ssl_path', '/etc/ssl/froxlor-custom/'), ('system', 'customer_ssl_path', '/etc/ssl/froxlor-custom/'),
('system', 'allow_error_report_admin', '1'), ('system', 'allow_error_report_admin', '1'),
('system', 'allow_error_report_customer', '0'), ('system', 'allow_error_report_customer', '0'),
@@ -623,7 +629,7 @@ opcache.interned_strings_buffer'),
('system', 'apacheitksupport', '0'), ('system', 'apacheitksupport', '0'),
('system', 'leprivatekey', 'unset'), ('system', 'leprivatekey', 'unset'),
('system', 'lepublickey', 'unset'), ('system', 'lepublickey', 'unset'),
('system', 'letsencryptca', 'production'), ('system', 'letsencryptca', 'letsencrypt'),
('system', 'letsencryptcountrycode', 'DE'), ('system', 'letsencryptcountrycode', 'DE'),
('system', 'letsencryptstate', 'Hessen'), ('system', 'letsencryptstate', 'Hessen'),
('system', 'letsencryptchallengepath', '/var/www/froxlor'), ('system', 'letsencryptchallengepath', '/var/www/froxlor'),
@@ -653,8 +659,8 @@ opcache.interned_strings_buffer'),
('system', 'leregistered', '0'), ('system', 'leregistered', '0'),
('system', 'leaccount', ''), ('system', 'leaccount', ''),
('system', 'nssextrausers', '0'), ('system', 'nssextrausers', '0'),
('system', 'disable_le_selfcheck', '0'), ('system', 'le_domain_dnscheck', '1'),
('system', 'ssl_protocols', 'TLSv1,TLSv1.2'), ('system', 'ssl_protocols', 'TLSv1.2'),
('system', 'tlsv13_cipher_list', ''), ('system', 'tlsv13_cipher_list', ''),
('system', 'honorcipherorder', '0'), ('system', 'honorcipherorder', '0'),
('system', 'sessiontickets', '1'), ('system', 'sessiontickets', '1'),
@@ -669,6 +675,14 @@ opcache.interned_strings_buffer'),
('system', 'froxloraliases', ''), ('system', 'froxloraliases', ''),
('system', 'apply_specialsettings_default', '1'), ('system', 'apply_specialsettings_default', '1'),
('system', 'apply_phpconfigs_default', '1'), ('system', 'apply_phpconfigs_default', '1'),
('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'), ('api', 'enabled', '0'),
('2fa', 'enabled', '1'), ('2fa', 'enabled', '1'),
('panel', 'decimal_places', '4'), ('panel', 'decimal_places', '4'),
@@ -681,7 +695,6 @@ opcache.interned_strings_buffer'),
('panel', 'paging', '20'), ('panel', 'paging', '20'),
('panel', 'natsorting', '1'), ('panel', 'natsorting', '1'),
('panel', 'sendalternativemail', '0'), ('panel', 'sendalternativemail', '0'),
('panel', 'no_robots', '1'),
('panel', 'allow_domain_change_admin', '0'), ('panel', 'allow_domain_change_admin', '0'),
('panel', 'allow_domain_change_customer', '0'), ('panel', 'allow_domain_change_customer', '0'),
('panel', 'frontend', 'froxlor'), ('panel', 'frontend', 'froxlor'),
@@ -703,8 +716,15 @@ opcache.interned_strings_buffer'),
('panel', 'password_special_char', '!?<>§$%+#=@'), ('panel', 'password_special_char', '!?<>§$%+#=@'),
('panel', 'customer_hide_options', ''), ('panel', 'customer_hide_options', ''),
('panel', 'is_configured', '0'), ('panel', 'is_configured', '0'),
('panel', 'version', '0.10.13'), ('panel', 'imprint_url', ''),
('panel', 'db_version', '201912313'); ('panel', 'terms_url', ''),
('panel', 'privacy_url', ''),
('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`; DROP TABLE IF EXISTS `panel_tasks`;
@@ -785,23 +805,6 @@ CREATE TABLE `panel_diskspace` (
DROP TABLE IF EXISTS `panel_diskspace_admins`;
CREATE TABLE `panel_diskspace_admins` (
`id` int(11) unsigned NOT NULL auto_increment,
`adminid` int(11) unsigned NOT NULL default '0',
`year` int(4) unsigned zerofill NOT NULL default '0000',
`month` int(2) unsigned zerofill NOT NULL default '00',
`day` int(2) unsigned zerofill NOT NULL default '00',
`stamp` int(11) unsigned NOT NULL default '0',
`webspace` bigint(30) unsigned NOT NULL default '0',
`mail` bigint(30) unsigned NOT NULL default '0',
`mysql` bigint(30) unsigned NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `adminid` (`adminid`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;
DROP TABLE IF EXISTS `panel_languages`; DROP TABLE IF EXISTS `panel_languages`;
CREATE TABLE `panel_languages` ( CREATE TABLE `panel_languages` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT, `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
@@ -820,7 +823,8 @@ INSERT INTO `panel_languages` (`id`, `language`, `iso`, `file`) VALUES
(4, 'Portugu&ecirc;s', 'pt', 'lng/portugues.lng.php'), (4, 'Portugu&ecirc;s', 'pt', 'lng/portugues.lng.php'),
(5, 'Italiano', 'it', 'lng/italian.lng.php'), (5, 'Italiano', 'it', 'lng/italian.lng.php'),
(6, 'Nederlands', 'nl', 'lng/dutch.lng.php'), (6, 'Nederlands', 'nl', 'lng/dutch.lng.php'),
(7, 'Svenska', 'sv', 'lng/swedish.lng.php'); (7, 'Svenska', 'sv', 'lng/swedish.lng.php'),
(8, '&#268;esk&aacute; republika', 'cs', 'lng/czech.lng.php');
DROP TABLE IF EXISTS `panel_syslog`; DROP TABLE IF EXISTS `panel_syslog`;
@@ -996,7 +1000,8 @@ CREATE TABLE IF NOT EXISTS `domain_ssl_settings` (
`ssl_csr_file` mediumtext, `ssl_csr_file` mediumtext,
`ssl_fullchain_file` mediumtext, `ssl_fullchain_file` mediumtext,
`expirationdate` datetime DEFAULT NULL, `expirationdate` datetime DEFAULT NULL,
PRIMARY KEY (`id`) PRIMARY KEY (`id`),
UNIQUE KEY (`domainid`)
) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci; ) ENGINE=InnoDB CHARSET=utf8 COLLATE=utf8_general_ci;

View File

@@ -123,7 +123,7 @@ class FroxlorInstall
if ((isset($_POST['installstep']) && $_POST['installstep'] == '1') || (isset($_GET['check']) && $_GET['check'] == '1')) { if ((isset($_POST['installstep']) && $_POST['installstep'] == '1') || (isset($_GET['check']) && $_GET['check'] == '1')) {
$pagetitle = $this->_lng['install']['title']; $pagetitle = $this->_lng['install']['title'];
if ($this->_checkPostData()) { if ($this->_checkPostData()) {
// ceck data and create userdata etc.etc.etc. // check data and create userdata etc.etc.etc.
$result = $this->_doInstall(); $result = $this->_doInstall();
} elseif (isset($_GET['check']) && $_GET['check'] == '1') { } elseif (isset($_GET['check']) && $_GET['check'] == '1') {
// gather data // gather data
@@ -159,13 +159,17 @@ class FroxlorInstall
$this->_guessServerName(); $this->_guessServerName();
$this->_guessServerIP(); $this->_guessServerIP();
$this->_guessWebserver(); $this->_guessWebserver();
$this->_guessDistribution();
$this->_getPostField('mysql_host', '127.0.0.1'); $this->_getPostField('mysql_host', '127.0.0.1');
$this->_getPostField('mysql_database', 'froxlor'); $this->_getPostField('mysql_database', 'froxlor');
$this->_getPostField('mysql_forcecreate', '0');
$this->_getPostField('mysql_unpriv_user', 'froxlor'); $this->_getPostField('mysql_unpriv_user', 'froxlor');
$this->_getPostField('mysql_unpriv_pass'); $this->_getPostField('mysql_unpriv_pass');
$this->_getPostField('mysql_root_user', 'root'); $this->_getPostField('mysql_root_user', 'root');
$this->_getPostField('mysql_root_pass'); $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_user', 'admin');
$this->_getPostField('admin_pass1'); $this->_getPostField('admin_pass1');
$this->_getPostField('admin_pass2'); $this->_getPostField('admin_pass2');
@@ -211,6 +215,12 @@ class FroxlorInstall
$options = array( $options = array(
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' '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'] . ";"; $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";";
$fatal_fail = false; $fatal_fail = false;
try { try {
@@ -245,15 +255,23 @@ class FroxlorInstall
$content .= $this->_status_message('green', "OK"); $content .= $this->_status_message('green', "OK");
// check for existing db and create backup if so // check for existing db and create backup if so
$content .= $this->_backupExistingDatabase($db_root); $content .= $this->_backupExistingDatabase($db_root);
// create unprivileged user and the database itself if (!$this->_abort) {
$content .= $this->_createDatabaseAndUser($db_root); // create unprivileged user and the database itself
// importing data to new database $content .= $this->_createDatabaseAndUser($db_root);
$content .= $this->_importDatabaseData(); // importing data to new database
$content .= $this->_importDatabaseData();
}
if (! $this->_abort) { if (! $this->_abort) {
// create DB object for new database // create DB object for new database
$options = array( $options = array(
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' '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'] . ";"; $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
$another_fail = false; $another_fail = false;
try { try {
@@ -323,35 +341,70 @@ class FroxlorInstall
$userdata .= "\$sql['user']='" . addcslashes($this->_data['mysql_unpriv_user'], "'\\") . "';\n"; $userdata .= "\$sql['user']='" . addcslashes($this->_data['mysql_unpriv_user'], "'\\") . "';\n";
$userdata .= "\$sql['password']='" . addcslashes($this->_data['mysql_unpriv_pass'], "'\\") . "';\n"; $userdata .= "\$sql['password']='" . addcslashes($this->_data['mysql_unpriv_pass'], "'\\") . "';\n";
$userdata .= "\$sql['db']='" . addcslashes($this->_data['mysql_database'], "'\\") . "';\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]['caption']='Default';\n";
$userdata .= "\$sql_root[0]['host']='" . addcslashes($this->_data['mysql_host'], "'\\") . "';\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]['user']='" . addcslashes($this->_data['mysql_root_user'], "'\\") . "';\n";
$userdata .= "\$sql_root[0]['password']='" . addcslashes($this->_data['mysql_root_pass'], "'\\") . "';\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 .= "// enable debugging to browser in case of SQL errors\n";
$userdata .= "\$sql['debug'] = false;\n"; $userdata .= "\$sql['debug'] = false;\n";
$userdata .= "?>"; $userdata .= "?>";
// test if we can store the userdata.inc.php in ../lib // test if we can store the userdata.inc.php in ../lib
$umask = @umask(077);
$userdata_file = dirname(dirname(dirname(__FILE__))) . '/lib/userdata.inc.php'; $userdata_file = dirname(dirname(dirname(__FILE__))) . '/lib/userdata.inc.php';
if ($fp = @fopen($userdata_file, 'w')) { if (@touch($userdata_file) && @is_writable($userdata_file)) {
$result = @fputs($fp, $userdata, strlen($userdata)); $fp = @fopen($userdata_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp); @fclose($fp);
$content .= $this->_status_message('green', 'OK'); $content .= $this->_status_message('green', 'OK');
chmod($userdata_file, 0440);
} elseif ($fp = @fopen('/tmp/userdata.inc.php', 'w')) {
$result = @fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
$content .= $this->_status_message('orange', $this->_lng['install']['creating_configfile_temp']);
chmod('/tmp/userdata.inc.php', 0440);
} else { } else {
$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']); @unlink($userdata_file);
$escpduserdata = nl2br(htmlspecialchars($userdata)); // try creating it in a temporary file
eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";"); $temp_file = @tempnam(sys_get_temp_dir(), 'fx');
if ($temp_file) {
$fp = @fopen($temp_file, 'w');
@fputs($fp, $userdata, strlen($userdata));
@fclose($fp);
$content .= $this->_status_message('orange', sprintf($this->_lng['install']['creating_configfile_temp'], $temp_file));
} else {
$content .= $this->_status_message('red', $this->_lng['install']['creating_configfile_failed']);
$escpduserdata = nl2br(htmlspecialchars($userdata));
eval("\$content .= \"" . $this->_getTemplate("textarea") . "\";");
}
} }
@umask($umask);
return $content; 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 * create corresponding entries in froxlor database
* *
@@ -395,8 +448,8 @@ class FroxlorInstall
$content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']); $content .= $this->_status_message('begin', $this->_lng['install']['adding_admin_user']);
$ins_data = array( $ins_data = array(
'loginname' => $this->_data['admin_user'], 'loginname' => $this->_data['admin_user'],
/* use SHA256 default crypt */ /* use SHA256 default crypt */
'password' => crypt($this->_data['admin_pass1'], '$5$' . md5(uniqid(microtime(), 1)) . md5(uniqid(microtime(), 1))), 'password' => crypt($this->_data['admin_pass1'], '$5$' . $this->genUniqueToken() . $this->genUniqueToken()),
'email' => 'admin@' . $this->_data['servername'], 'email' => 'admin@' . $this->_data['servername'],
'deflang' => $this->_languages[$this->_activelng] 'deflang' => $this->_languages[$this->_activelng]
); );
@@ -497,12 +550,30 @@ class FroxlorInstall
$this->_updateSetting($upd_stmt, 'error', 'system', 'errorlog_level'); $this->_updateSetting($upd_stmt, 'error', 'system', 'errorlog_level');
} }
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
if ($this->_data['distribution'] == str_replace(".xml", "", strtolower(basename($_distribution)))) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$defaults = $dist->getDefaults();
foreach ($defaults->property as $property) {
$this->_updateSetting($upd_stmt, $property->value, $property->settinggroup, $property->varname);
}
}
}
$this->_updateSetting($upd_stmt, $this->_data['activate_newsfeed'], 'admin', 'show_news_feed'); $this->_updateSetting($upd_stmt, $this->_data['activate_newsfeed'], 'admin', 'show_news_feed');
$this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath'); $this->_updateSetting($upd_stmt, dirname(dirname(dirname(__FILE__))), 'system', 'letsencryptchallengepath');
// insert the lastcronrun to be the installation date // insert the lastcronrun to be the installation date
$this->_updateSetting($upd_stmt, time(), 'system', 'lastcronrun'); $this->_updateSetting($upd_stmt, time(), 'system', 'lastcronrun');
// check currently used php version and set values of fpm/fcgid accordingly
if (defined('PHP_MAJOR_VERSION') && defined('PHP_MINOR_VERSION')) {
$reload = "service php" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "-fpm restart";
$config_dir = "/etc/php/" . PHP_MAJOR_VERSION . "." . PHP_MINOR_VERSION . "/fpm/pool.d/";
$db->query("UPDATE `" . TABLE_PANEL_FPMDAEMONS . "` SET `reload_cmd` = '" . $reload . "', `config_dir` = '" . $config_dir . "' WHERE `id` ='1';");
}
// set specific times for some crons (traffic only at night, etc.) // set specific times for some crons (traffic only at night, etc.)
$ts = mktime(0, 0, 0, date('m', time()), date('d', time()), date('Y', time())); $ts = mktime(0, 0, 0, date('m', time()), date('d', time()), date('Y', time()));
$db->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic';"); $db->query("UPDATE `" . TABLE_PANEL_CRONRUNS . "` SET `lastrun` = '" . $ts . "' WHERE `cronfile` ='cron_traffic';");
@@ -529,6 +600,12 @@ class FroxlorInstall
$options = array( $options = array(
'PDO::MYSQL_ATTR_INIT_COMMAND' => 'SET names utf8' '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'] . ";"; $dsn = "mysql:host=" . $this->_data['mysql_host'] . ";dbname=" . $this->_data['mysql_database'] . ";";
$fatal_fail = false; $fatal_fail = false;
try { try {
@@ -563,7 +640,7 @@ class FroxlorInstall
for ($i = 0; $i < sizeof($sql_query); $i ++) { for ($i = 0; $i < sizeof($sql_query); $i ++) {
if (trim($sql_query[$i]) != '') { if (trim($sql_query[$i]) != '') {
try { try {
$result = $db->query($sql_query[$i]); $db->query($sql_query[$i]);
} catch (\PDOException $e) { } catch (\PDOException $e) {
$content .= $this->_status_message('red', $e->getMessage()); $content .= $this->_status_message('red', $e->getMessage());
$fatal_fail = true; $fatal_fail = true;
@@ -661,7 +738,7 @@ class FroxlorInstall
if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) { if (version_compare($db_root->getAttribute(\PDO::ATTR_SERVER_VERSION), '8.0.11', '>=')) {
// create user // create user
$stmt = $db_root->prepare(" $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( $stmt->execute(array(
"password" => $password "password" => $password
@@ -707,39 +784,59 @@ class FroxlorInstall
)); ));
$rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn(); $rows = $db_root->query("SELECT FOUND_ROWS()")->fetchColumn();
$content .= $this->_status_message('begin', $this->_lng['install']['check_db_exists']);
// check result // check result
if ($result_stmt !== false && $rows > 0) { if ($result_stmt !== false && $rows > 0) {
$tables_exist = true; $tables_exist = true;
} }
if ($tables_exist) { if ($tables_exist) {
// tell whats going on if ((int)$this->_data['mysql_forcecreate'] > 0) {
$content .= $this->_status_message('begin', $this->_lng['install']['backup_old_db']); // 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 // create temporary backup-filename
$filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql"; $filename = "/tmp/froxlor_backup_" . date('YmdHi') . ".sql";
// look for mysqldump // look for mysqldump
$do_backup = false; $do_backup = false;
if (file_exists("/usr/bin/mysqldump")) { if (file_exists("/usr/bin/mysqldump")) {
$do_backup = true; $do_backup = true;
$mysql_dump = '/usr/bin/mysqldump'; $mysql_dump = '/usr/bin/mysqldump';
} elseif (file_exists("/usr/local/bin/mysqldump")) { } elseif (file_exists("/usr/local/bin/mysqldump")) {
$do_backup = true; $do_backup = true;
$mysql_dump = '/usr/local/bin/mysqldump'; $mysql_dump = '/usr/local/bin/mysqldump';
} }
if ($do_backup) { // create temporary .cnf file
$command = $mysql_dump . " " . $this->_data['mysql_database'] . " -u " . $this->_data['mysql_root_user'] . " --password='" . $this->_data['mysql_root_pass'] . "' --result-file=" . $filename; $cnffilename = "/tmp/froxlor_dump.cnf";
$output = exec($command); $dumpcnf = "[mysqldump]" . PHP_EOL . "password=\"" . $this->_data['mysql_root_pass'] . "\"" . PHP_EOL;
if (stristr($output, "error")) { file_put_contents($cnffilename, $dumpcnf);
$content .= $this->_status_message('red', $this->_lng['install']['backup_failed']);
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 { } else {
$content .= $this->_status_message('green', 'OK (' . $filename . ')'); $content .= $this->_status_message('red', $this->_lng['install']['backup_binary_missing']);
$this->_abort = true;
} }
} else { } 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; return $content;
@@ -758,7 +855,7 @@ class FroxlorInstall
} }
// language selection // language selection
$language_options = ''; $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); $language_options .= \Froxlor\UI\HTML::makeoption($language_name, $language_file, $this->_activelng, true, true);
} }
// get language-form-template // get language-form-template
@@ -775,6 +872,8 @@ class FroxlorInstall
$formdata .= $this->_getSectionItemString('mysql_host', true); $formdata .= $this->_getSectionItemString('mysql_host', true);
// database // database
$formdata .= $this->_getSectionItemString('mysql_database', true); $formdata .= $this->_getSectionItemString('mysql_database', true);
// database overwrite if exists?
$formdata .= $this->_getSectionItemYesNo('mysql_forcecreate', false);
// unpriv-user has to be different from root // unpriv-user has to be different from root
if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) { if ($this->_data['mysql_unpriv_user'] == $this->_data['mysql_root_user']) {
$style = 'blue'; $style = 'blue';
@@ -804,6 +903,9 @@ class FroxlorInstall
} }
$formdata .= $this->_getSectionItemString('mysql_root_pass', true, $style, 'password'); $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 * admin data
*/ */
@@ -833,6 +935,37 @@ class FroxlorInstall
*/ */
$section = $this->_lng['install']['serversettings']; $section = $this->_lng['install']['serversettings'];
eval("\$formdata .= \"" . $this->_getTemplate("datasection") . "\";"); eval("\$formdata .= \"" . $this->_getTemplate("datasection") . "\";");
// distribution
if (! empty($_POST['installstep']) && $this->_data['distribution'] == '') {
$diststyle = 'color:red;';
} else {
$diststyle = '';
}
// 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'] ?? '');
// $this->_data['distribution']
}
$formdata .= $this->_getSectionItemSelectbox('distribution', $distributions_select, $diststyle);
// servername // servername
if (! empty($_POST['installstep']) && $this->_data['servername'] == '') { if (! empty($_POST['installstep']) && $this->_data['servername'] == '') {
$style = 'color:red;'; $style = 'color:red;';
@@ -854,12 +987,12 @@ class FroxlorInstall
$websrvstyle = ''; $websrvstyle = '';
} }
// apache // apache
$formdata .= $this->_getSectionItemCheckbox('apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle); $formdata .= $this->_getSectionItemCheckbox('webserver', 'apache2', ($this->_data['webserver'] == 'apache2'), $websrvstyle);
$formdata .= $this->_getSectionItemCheckbox('apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle); $formdata .= $this->_getSectionItemCheckbox('webserver', 'apache24', ($this->_data['webserver'] == 'apache24'), $websrvstyle);
// lighttpd // lighttpd
$formdata .= $this->_getSectionItemCheckbox('lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle); $formdata .= $this->_getSectionItemCheckbox('webserver', 'lighttpd', ($this->_data['webserver'] == 'lighttpd'), $websrvstyle);
// nginx // nginx
$formdata .= $this->_getSectionItemCheckbox('nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle); $formdata .= $this->_getSectionItemCheckbox('webserver', 'nginx', ($this->_data['webserver'] == 'nginx'), $websrvstyle);
// webserver-user // webserver-user
if (! empty($_POST['installstep']) && $this->_data['httpuser'] == '') { if (! empty($_POST['installstep']) && $this->_data['httpuser'] == '') {
$style = 'color:red;'; $style = 'color:red;';
@@ -911,7 +1044,7 @@ class FroxlorInstall
} }
/** /**
* generate form radio field for webserver-selection * generate form radio field
* *
* @param string $fieldname * @param string $fieldname
* @param boolean $checked * @param boolean $checked
@@ -919,8 +1052,9 @@ class FroxlorInstall
* *
* @return string * @return string
*/ */
private function _getSectionItemCheckbox($fieldname = null, $checked = false, $style = "") private function _getSectionItemCheckbox($groupname = null, $fieldname = null, $checked = false, $style = "")
{ {
$groupname = $this->_lng['install'][$groupname];
$fieldlabel = $this->_lng['install'][$fieldname]; $fieldlabel = $this->_lng['install'][$fieldname];
if ($checked) { if ($checked) {
$checked = 'checked="checked"'; $checked = 'checked="checked"';
@@ -930,6 +1064,24 @@ class FroxlorInstall
return $sectionitem; return $sectionitem;
} }
/**
* generate form selectbox
*
* @param string $fieldname
* @param boolean $options
* @param string $style
*
* @return string
*/
private function _getSectionItemSelectbox($fieldname = null, $options = null, $style = "")
{
$fieldlabel = $this->_lng['install'][$fieldname];
$sectionitem = "";
eval("\$sectionitem .= \"" . $this->_getTemplate("dataitemselect") . "\";");
return $sectionitem;
}
/** /**
* generate form checkbox field * generate form checkbox field
* *
@@ -964,11 +1116,11 @@ class FroxlorInstall
// check for correct php version // check for correct php version
$content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']); $content .= $this->_status_message('begin', $this->_lng['requirements']['phpversion']);
if (version_compare("7.0.0", PHP_VERSION, ">=")) { if (version_compare("7.1.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')'); $content .= $this->_status_message('red', $this->_lng['requirements']['notfound'] . ' (' . PHP_VERSION . ')');
$_die = true; $_die = true;
} else { } else {
if (version_compare("7.1.0", PHP_VERSION, ">=")) { if (version_compare("7.4.0", PHP_VERSION, ">=")) {
$content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')'); $content .= $this->_status_message('orange', $this->_lng['requirements']['newerphpprefered'] . ' (' . PHP_VERSION . ')');
} else { } else {
$content .= $this->_status_message('green', PHP_VERSION); $content .= $this->_status_message('green', PHP_VERSION);
@@ -1234,10 +1386,12 @@ class FroxlorInstall
// from form // from form
if (! empty($_POST['serverip'])) { if (! empty($_POST['serverip'])) {
$this->_data['serverip'] = $_POST['serverip']; $this->_data['serverip'] = $_POST['serverip'];
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
return; return;
// from $_SERVER // from $_SERVER
} elseif (! empty($_SERVER['SERVER_ADDR'])) { } elseif (! empty($_SERVER['SERVER_ADDR'])) {
$this->_data['serverip'] = $_SERVER['SERVER_ADDR']; $this->_data['serverip'] = $_SERVER['SERVER_ADDR'];
$this->_data['serverip'] = inet_ntop(inet_pton($this->_data['serverip']));
return; return;
} }
// empty // empty
@@ -1266,6 +1420,49 @@ class FroxlorInstall
} }
} }
/**
* get/guess linux distribution
*/
private function _guessDistribution()
{
// post
if (! empty($_POST['distribution'])) {
$this->_data['distribution'] = $_POST['distribution'];
} else {
// set default os.
$os_dist = array(
'ID' => 'buster'
);
$os_version = array(
'0' => '10'
);
// read os-release
if (file_exists('/etc/os-release')) {
$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];
}
}
$distros = glob(\Froxlor\FileDir::makeCorrectDir(\Froxlor\Froxlor::getInstallDir() . '/lib/configfiles/') . '*.xml');
foreach ($distros as $_distribution) {
$dist = new \Froxlor\Config\ConfigParser($_distribution);
$ver = explode('.', $dist->distributionVersion)[0];
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
$this->_data['distribution'] = str_replace(".xml", "", strtolower(basename($_distribution)));
}
}
}
}
/** /**
* check if POST field is set and get value for the * check if POST field is set and get value for the
* internal data array, if not set use either '' or $default if != null * internal data array, if not set use either '' or $default if != null

View File

@@ -30,6 +30,7 @@
*/ */
function showUpdateStep($task = null, $needs_status = true) function showUpdateStep($task = null, $needs_status = true)
{ {
set_time_limit(30);
if (! $needs_status) if (! $needs_status)
echo "<b>"; echo "<b>";
@@ -41,7 +42,6 @@ function showUpdateStep($task = null, $needs_status = true)
} }
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task);
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, $task);
} }
/** /**
@@ -82,7 +82,6 @@ function lastStepStatus($status = -1, $message = '')
if ($status == - 1 || $status == 2) { if ($status == - 1 || $status == 2) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!'); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!');
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Attention - last update task failed!!!');
} elseif ($status == 0 || $status == 1) { } elseif ($status == 0 || $status == 1) {
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Success'); \Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, 'Success');
} }

View File

@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'no';
$lng['requirements']['notfound'] = 'not found'; $lng['requirements']['notfound'] = 'not found';
$lng['requirements']['notinstalled'] = 'not installed'; $lng['requirements']['notinstalled'] = 'not installed';
$lng['requirements']['activated'] = 'enabled'; $lng['requirements']['activated'] = 'enabled';
$lng['requirements']['phpversion'] = 'PHP version >= 7.0'; $lng['requirements']['phpversion'] = 'PHP version >= 7.1';
$lng['requirements']['newerphpprefered'] = 'Good, but php-7.1 is prefered.'; $lng['requirements']['newerphpprefered'] = 'Good, but php-7.4 is preferred.';
$lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...'; $lng['requirements']['phppdo'] = 'PHP PDO extension and PDO-MySQL driver...';
$lng['requirements']['phpsession'] = 'PHP session-extension...'; $lng['requirements']['phpsession'] = 'PHP session-extension...';
$lng['requirements']['phpctype'] = 'PHP ctype-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']['bcmathdescription'] = 'Traffic-calculation related functions will not work correctly!';
$lng['requirements']['zipdescription'] = 'The auto-update feature requires the zip extension.'; $lng['requirements']['zipdescription'] = 'The auto-update feature requires the zip extension.';
$lng['requirements']['openbasedir'] = 'open_basedir...'; $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']['mysqldump'] = 'MySQL dump tool';
$lng['requirements']['mysqldumpmissing'] = 'Automatic backup of possible existing database is not possible. Please install mysql-client tools'; $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.'; $lng['requirements']['diedbecauseofrequirements'] = 'Cannot install Froxlor without these requirements! Try to fix them and retry.';
@@ -53,16 +53,20 @@ $lng['install']['welcometext'] = 'Thank you for choosing Froxlor. Please fill ou
$lng['install']['database'] = 'Database connection'; $lng['install']['database'] = 'Database connection';
$lng['install']['mysql_host'] = 'MySQL-Hostname'; $lng['install']['mysql_host'] = 'MySQL-Hostname';
$lng['install']['mysql_database'] = 'Database name'; $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_user'] = 'Username for the unprivileged MySQL-account';
$lng['install']['mysql_unpriv_pass'] = 'Password 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_user'] = 'Username for the MySQL-root-account';
$lng['install']['mysql_root_pass'] = 'Password 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_account'] = 'Administrator Account';
$lng['install']['admin_user'] = 'Administrator Username'; $lng['install']['admin_user'] = 'Administrator Username';
$lng['install']['admin_pass1'] = 'Administrator Password'; $lng['install']['admin_pass1'] = 'Administrator Password';
$lng['install']['admin_pass2'] = 'Administrator-Password (confirm)'; $lng['install']['admin_pass2'] = 'Administrator-Password (confirm)';
$lng['install']['activate_newsfeed'] = 'Enable the official newsfeed<br><small>(https://inside.froxlor.org/news/)</small>'; $lng['install']['activate_newsfeed'] = 'Enable the official newsfeed<br><small>(https://inside.froxlor.org/news/)</small>';
$lng['install']['serversettings'] = 'Server settings'; $lng['install']['serversettings'] = 'Server settings';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Server name (FQDN, no ip-address)'; $lng['install']['servername'] = 'Server name (FQDN, no ip-address)';
$lng['install']['serverip'] = 'Server IP'; $lng['install']['serverip'] = 'Server IP';
$lng['install']['webserver'] = 'Webserver'; $lng['install']['webserver'] = 'Webserver';
@@ -78,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_old_db'] = 'Creating backup of old database...';
$lng['install']['backup_binary_missing'] = 'Could not find mysqldump'; $lng['install']['backup_binary_missing'] = 'Could not find mysqldump';
$lng['install']['backup_failed'] = 'Could not backup database'; $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']['prepare_db'] = 'Preparing database...';
$lng['install']['create_mysqluser_and_db'] = 'Creating database and username...'; $lng['install']['create_mysqluser_and_db'] = 'Creating database and username...';
$lng['install']['testing_new_db'] = 'Testing if database and user have been created correctly...'; $lng['install']['testing_new_db'] = 'Testing if database and user have been created correctly...';
@@ -86,7 +92,7 @@ $lng['install']['changing_data'] = 'Adjusting settings...';
$lng['install']['creating_entries'] = 'Inserting new values...'; $lng['install']['creating_entries'] = 'Inserting new values...';
$lng['install']['adding_admin_user'] = 'Creating admin-account...'; $lng['install']['adding_admin_user'] = 'Creating admin-account...';
$lng['install']['creating_configfile'] = 'Creating configfile...'; $lng['install']['creating_configfile'] = 'Creating configfile...';
$lng['install']['creating_configfile_temp'] = 'File was saved in /tmp/userdata.inc.php, please move to ' . dirname(dirname(__DIR__)) . '/lib/.'; $lng['install']['creating_configfile_temp'] = 'File was saved in %s, please move to ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_failed'] = 'Could not create ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, please create it manually with the following content:'; $lng['install']['creating_configfile_failed'] = 'Could not create ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, please create it manually with the following content:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor was installed successfully.'; $lng['install']['froxlor_succ_installed'] = 'Froxlor was installed successfully.';

View File

@@ -22,7 +22,7 @@ $lng['requirements']['not_true'] = 'non';
$lng['requirements']['notfound'] = 'introuvable'; $lng['requirements']['notfound'] = 'introuvable';
$lng['requirements']['notinstalled'] = 'non installé'; $lng['requirements']['notinstalled'] = 'non installé';
$lng['requirements']['activated'] = 'activé'; $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']['phppdo'] = 'extension PHP PDO et pilote PDO-MySQL ...';
$lng['requirements']['phpxml'] = 'extension PHP XML...'; $lng['requirements']['phpxml'] = 'extension PHP XML...';
$lng['requirements']['phpfilter'] = 'extension PHP filter ...'; $lng['requirements']['phpfilter'] = 'extension PHP filter ...';
@@ -53,6 +53,7 @@ $lng['install']['admin_user'] = 'Nom d\'utilisateur administrateur';
$lng['install']['admin_pass1'] = 'Mot de passe administrateur'; $lng['install']['admin_pass1'] = 'Mot de passe administrateur';
$lng['install']['admin_pass2'] = 'Mot de passe administrateur (confirmez)'; $lng['install']['admin_pass2'] = 'Mot de passe administrateur (confirmez)';
$lng['install']['serversettings'] = 'Réglages serveur'; $lng['install']['serversettings'] = 'Réglages serveur';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Nom du serveur (FQDN, pas d\'adresse IP)'; $lng['install']['servername'] = 'Nom du serveur (FQDN, pas d\'adresse IP)';
$lng['install']['serverip'] = 'Adresse IP du serveur'; $lng['install']['serverip'] = 'Adresse IP du serveur';
$lng['install']['webserver'] = 'Serveur Web'; $lng['install']['webserver'] = 'Serveur Web';
@@ -76,7 +77,7 @@ $lng['install']['changing_data'] = 'Ajustement des paramètres...';
$lng['install']['creating_entries'] = 'Insertion des nouvelles valeurs...'; $lng['install']['creating_entries'] = 'Insertion des nouvelles valeurs...';
$lng['install']['adding_admin_user'] = 'Création du compte administrateur...'; $lng['install']['adding_admin_user'] = 'Création du compte administrateur...';
$lng['install']['creating_configfile'] = 'Création du fichier de configuration...'; $lng['install']['creating_configfile'] = 'Création du fichier de configuration...';
$lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans /tmp/userdata.inc.php, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/.'; $lng['install']['creating_configfile_temp'] = 'Le fichier a été enregistré dans %s, merci de le déplacer dans ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php';
$lng['install']['creating_configfile_failed'] = 'Impossible de créer ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:'; $lng['install']['creating_configfile_failed'] = 'Impossible de créer ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php, merci de le créer manuellement avec le contenu suivant:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor a été installé avec succès.'; $lng['install']['froxlor_succ_installed'] = 'Froxlor a été installé avec succès.';

View File

@@ -22,8 +22,8 @@ $lng['requirements']['not_true'] = 'nein';
$lng['requirements']['notfound'] = 'nicht gefunden'; $lng['requirements']['notfound'] = 'nicht gefunden';
$lng['requirements']['notinstalled'] = 'nicht installiert'; $lng['requirements']['notinstalled'] = 'nicht installiert';
$lng['requirements']['activated'] = 'ist aktiviert.'; $lng['requirements']['activated'] = 'ist aktiviert.';
$lng['requirements']['phpversion'] = 'PHP Version >= 7.0'; $lng['requirements']['phpversion'] = 'PHP Version >= 7.1';
$lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.1 wird bevorzugt.'; $lng['requirements']['newerphpprefered'] = 'Passt, aber php-7.4 wird bevorzugt.';
$lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...'; $lng['requirements']['phppdo'] = 'PHP PDO Erweiterung und PDO-MySQL Treiber...';
$lng['requirements']['phpsession'] = 'PHP session-Erweiterung...'; $lng['requirements']['phpsession'] = 'PHP session-Erweiterung...';
$lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...'; $lng['requirements']['phpctype'] = 'PHP ctype-Erweiterung...';
@@ -53,16 +53,20 @@ $lng['install']['welcometext'] = 'Vielen Dank dass Sie sich für Froxlor entschi
$lng['install']['database'] = 'Datenbankverbindung'; $lng['install']['database'] = 'Datenbankverbindung';
$lng['install']['mysql_host'] = 'MySQL-Hostname'; $lng['install']['mysql_host'] = 'MySQL-Hostname';
$lng['install']['mysql_database'] = 'Datenbank Name'; $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_user'] = 'Benutzername für den unprivilegierten MySQL-Account';
$lng['install']['mysql_unpriv_pass'] = 'Passwort 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_user'] = 'Benutzername für den MySQL-Root-Account';
$lng['install']['mysql_root_pass'] = 'Passwort 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_account'] = 'Admin-Zugang';
$lng['install']['admin_user'] = 'Administrator-Benutzername'; $lng['install']['admin_user'] = 'Administrator-Benutzername';
$lng['install']['admin_pass1'] = 'Administrator-Passwort'; $lng['install']['admin_pass1'] = 'Administrator-Passwort';
$lng['install']['admin_pass2'] = 'Administrator-Passwort (Bestätigung)'; $lng['install']['admin_pass2'] = 'Administrator-Passwort (Bestätigung)';
$lng['install']['activate_newsfeed'] = 'Aktiviere das offizielle Newsfeed<br><small>(https://inside.froxlor.org/news/)</small>'; $lng['install']['activate_newsfeed'] = 'Aktiviere das offizielle Newsfeed<br><small>(https://inside.froxlor.org/news/)</small>';
$lng['install']['serversettings'] = 'Servereinstellungen'; $lng['install']['serversettings'] = 'Servereinstellungen';
$lng['install']['distribution'] = 'Distribution';
$lng['install']['servername'] = 'Servername (FQDN, keine IP-Adresse)'; $lng['install']['servername'] = 'Servername (FQDN, keine IP-Adresse)';
$lng['install']['serverip'] = 'Server-IP'; $lng['install']['serverip'] = 'Server-IP';
$lng['install']['webserver'] = 'Webserver'; $lng['install']['webserver'] = 'Webserver';
@@ -78,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_old_db'] = 'Sicherung vorheriger Datenbank...';
$lng['install']['backup_binary_missing'] = 'Konnte mysqldump nicht finden'; $lng['install']['backup_binary_missing'] = 'Konnte mysqldump nicht finden';
$lng['install']['backup_failed'] = 'Sicherung fehlgeschlagen'; $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']['prepare_db'] = 'Datenbank wird vorbereitet...';
$lng['install']['create_mysqluser_and_db'] = 'Erstelle Datenbank und Benutzer...'; $lng['install']['create_mysqluser_and_db'] = 'Erstelle Datenbank und Benutzer...';
$lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt angelegt wurden...'; $lng['install']['testing_new_db'] = 'Teste, ob Datenbank und Benutzer korrekt angelegt wurden...';
@@ -86,7 +92,7 @@ $lng['install']['changing_data'] = 'Einstellungen anpassen...';
$lng['install']['creating_entries'] = 'Trage neue Werte ein...'; $lng['install']['creating_entries'] = 'Trage neue Werte ein...';
$lng['install']['adding_admin_user'] = 'Erstelle Admin-Benutzer...'; $lng['install']['adding_admin_user'] = 'Erstelle Admin-Benutzer...';
$lng['install']['creating_configfile'] = 'Erstelle Konfigurationsdatei...'; $lng['install']['creating_configfile'] = 'Erstelle Konfigurationsdatei...';
$lng['install']['creating_configfile_temp'] = 'Datei wurde in /tmp/userdata.inc.php gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/ verschieben.'; $lng['install']['creating_configfile_temp'] = 'Datei wurde in %s gespeichert, bitte nach ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php verschieben.';
$lng['install']['creating_configfile_failed'] = 'Konnte ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:'; $lng['install']['creating_configfile_failed'] = 'Konnte ' . dirname(dirname(__DIR__)) . '/lib/userdata.inc.php nicht erstellen, bitte manuell mit folgendem Inhalt anlegen:';
$lng['install']['froxlor_succ_installed'] = 'Froxlor wurde erfolgreich installiert.'; $lng['install']['froxlor_succ_installed'] = 'Froxlor wurde erfolgreich installiert.';

View 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());
}

View File

@@ -1,4 +1,4 @@
<p> <p>
<label for="{$fieldname}" class="install-block {$style}">{$this->_lng['install']['webserver']} {$fieldlabel}:</label> <label for="{$fieldname}" class="install-block {$style}">{$groupname} {$fieldlabel}:</label>
<input type="radio" name="webserver" id="{$fieldname}" value="{$fieldname}" {$checked} /><span>{$fieldlabel}</span> <input type="radio" name="{$groupname}" id="{$fieldname}" value="{$fieldname}" {$checked} /><span>{$fieldlabel}</span>
</p> </p>

View File

@@ -0,0 +1,6 @@
<p>
<label for="{$fieldname}" class="install-block {$style}">{$fieldlabel}:</label>
<select name="{$fieldname}" id="{$fieldname}" class="dropdown">
{$options}
</select>
</p>

View File

@@ -1,6 +1,7 @@
<?php <?php
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Settings; use Froxlor\Settings;
use Froxlor\Validate\Validate;
/** /**
* This file is part of the Froxlor project. * This file is part of the Froxlor project.
@@ -546,7 +547,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.10')) {
if (\Froxlor\Froxlor::isDatabaseVersion('201912311')) { if (\Froxlor\Froxlor::isDatabaseVersion('201912311')) {
showUpdateStep("Migrate logfiles_format setting"); showUpdateStep("Migrate logfiles_format setting");
$current_format = Settings::Set('system.logfiles_format'); $current_format = Settings::Set('system.logfiles_format');
if (!empty($current_format)) { if (! empty($current_format)) {
Settings::Set('system.logfiles_format', '"' . Settings::Get('system.logfiles_format') . '"'); Settings::Set('system.logfiles_format', '"' . Settings::Get('system.logfiles_format') . '"');
lastStepStatus(0); lastStepStatus(0);
} else { } else {
@@ -571,3 +572,401 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.10.12')) {
showUpdateStep("Updating from 0.10.12 to 0.10.13", false); showUpdateStep("Updating from 0.10.12 to 0.10.13", false);
\Froxlor\Froxlor::updateToVersion('0.10.13'); \Froxlor\Froxlor::updateToVersion('0.10.13');
} }
if (\Froxlor\Froxlor::isDatabaseVersion('201912313')) {
showUpdateStep("Adding new field to domains table");
Database::query("ALTER TABLE `" . TABLE_PANEL_DOMAINS . "` ADD `domain_ace` varchar(255) NOT NULL default '' AFTER `domain`;");
lastStepStatus(0);
showUpdateStep("Updating domain entries");
$upd_stmt = Database::prepare("UPDATE `" . TABLE_PANEL_DOMAINS . "` SET `domain_ace` = :ace WHERE `id` = :domainid");
$sel_stmt = Database::prepare("SELECT id, domain FROM `" . TABLE_PANEL_DOMAINS . "` ORDER BY id ASC");
Database::pexecute($sel_stmt);
$idna_convert = new \Froxlor\Idna\IdnaWrapper();
while ($domain = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
Database::pexecute($upd_stmt, [
'ace' => $idna_convert->decode($domain['domain']),
'domainid' => $domain['id']
]);
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202002290');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.13')) {
showUpdateStep("Updating from 0.10.13 to 0.10.14", false);
\Froxlor\Froxlor::updateToVersion('0.10.14');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.14')) {
showUpdateStep("Updating from 0.10.14 to 0.10.15", false);
\Froxlor\Froxlor::updateToVersion('0.10.15');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202002290')) {
showUpdateStep("Adding new setting to validate DNS when using Let's Encrypt");
Database::query("DELETE FROM `" . TABLE_PANEL_SETTINGS . "` WHERE `settinggroup` = 'system' AND `varname` = 'disable_le_selfcheck'");
$le_domain_dnscheck = isset($_POST['system_le_domain_dnscheck']) ? (int) $_POST['system_le_domain_dnscheck'] : '1';
Settings::AddNew("system.le_domain_dnscheck", $le_domain_dnscheck);
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202004140');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.15')) {
showUpdateStep("Updating from 0.10.15 to 0.10.16", false);
\Froxlor\Froxlor::updateToVersion('0.10.16');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202004140')) {
showUpdateStep("Adding unique key on domainid field in domain ssl table");
// check for duplicate entries prior to set a unique key to avoid errors on update
Database::query("
DELETE a.* FROM domain_ssl_settings AS a
LEFT JOIN domain_ssl_settings AS b ON
((b.`domainid`=a.`domainid` AND UNIX_TIMESTAMP(b.`expirationdate`) > UNIX_TIMESTAMP(a.`expirationdate`))
OR (UNIX_TIMESTAMP(b.`expirationdate`) = UNIX_TIMESTAMP(a.`expirationdate`) AND b.`id`>a.`id`))
WHERE b.`id` IS NOT NULL
");
Database::query("ALTER TABLE `domain_ssl_settings` ADD UNIQUE(`domainid`)");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202005150');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.16')) {
showUpdateStep("Updating from 0.10.16 to 0.10.17", false);
\Froxlor\Froxlor::updateToVersion('0.10.17');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.17')) {
showUpdateStep("Updating from 0.10.17 to 0.10.18", false);
\Froxlor\Froxlor::updateToVersion('0.10.18');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.18')) {
showUpdateStep("Updating from 0.10.18 to 0.10.19", false);
\Froxlor\Froxlor::updateToVersion('0.10.19');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202005150')) {
showUpdateStep("Add new performance indexes", true);
Database::query("ALTER TABLE panel_customers ADD INDEX guid (guid);");
Database::query("ALTER TABLE panel_tasks ADD INDEX type (type);");
Database::query("ALTER TABLE mail_users ADD INDEX username (username);");
Database::query("ALTER TABLE mail_users ADD INDEX imap (imap);");
Database::query("ALTER TABLE mail_users ADD INDEX pop3 (pop3);");
Database::query("ALTER TABLE ftp_groups ADD INDEX gid (gid);");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202007240');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.19')) {
showUpdateStep("Updating from 0.10.19 to 0.10.20", false);
\Froxlor\Froxlor::updateToVersion('0.10.20');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202007240')) {
showUpdateStep("Removing old unused table", true);
Database::query("DROP TABLE IF EXISTS `panel_diskspace_admins`;");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202009070');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.20')) {
showUpdateStep("Updating from 0.10.20 to 0.10.21", false);
\Froxlor\Froxlor::updateToVersion('0.10.21');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.21')) {
showUpdateStep("Adding settings for ssl-vhost default content if not updated from db-version 201910110", true);
Settings::AddNew("system.default_sslvhostconf", '');
lastStepStatus(0);
showUpdateStep("Updating from 0.10.21 to 0.10.22", false);
\Froxlor\Froxlor::updateToVersion('0.10.22');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.22')) {
showUpdateStep("Updating from 0.10.22 to 0.10.23", false);
\Froxlor\Froxlor::updateToVersion('0.10.23');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23')) {
showUpdateStep("Updating from 0.10.23 to 0.10.23.1", false);
\Froxlor\Froxlor::updateToVersion('0.10.23.1');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202009070')) {
showUpdateStep("Adding setting to hide incompatible settings", true);
Settings::AddNew("system.hide_incompatible_settings", '0');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202012300');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202012300')) {
showUpdateStep("Adding setting for DKIM private key extension/suffix", true);
Settings::AddNew("dkim.privkeysuffix", '.priv');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202101200');
}
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.23.1')) {
showUpdateStep("Updating from 0.10.23.1 to 0.10.24", false);
\Froxlor\Froxlor::updateToVersion('0.10.24');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202101200')) {
showUpdateStep("Adding setting for mail address used in SOA records", true);
Settings::AddNew("system.soaemail", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202102200');
}
/*
* skip due to potential "1118 Row size too large" error
*
if (\Froxlor\Froxlor::isDatabaseVersion('202102200')) {
showUpdateStep("Add new description fields to mail and domain table", true);
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103030');
}
*/
if (\Froxlor\Froxlor::isFroxlorVersion('0.10.24')) {
showUpdateStep("Updating from 0.10.24 to 0.10.25", false);
\Froxlor\Froxlor::updateToVersion('0.10.25');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202102200') || \Froxlor\Froxlor::isDatabaseVersion('202103030')) {
showUpdateStep("Refactoring columns from large tables", true);
Database::query("ALTER TABLE panel_domains CHANGE `ssl_protocols` `ssl_protocols` varchar(255) NOT NULL DEFAULT '';");
Database::query("ALTER TABLE panel_domains CHANGE `ssl_cipher_list` `ssl_cipher_list` varchar(500) NOT NULL DEFAULT '';");
Database::query("ALTER TABLE panel_domains CHANGE `tlsv13_cipher_list` `tlsv13_cipher_list` varchar(500) NOT NULL DEFAULT '';");
lastStepStatus(0);
showUpdateStep("Add new description fields to mail and domain table", true);
$result = Database::query("DESCRIBE `panel_domains`");
$columnfound = 0;
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
if ($row['Field'] == 'description') {
$columnfound = 1;
}
}
if (! $columnfound) {
Database::query("ALTER TABLE panel_domains ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `ssl_sessiontickets`;");
}
$result = Database::query("DESCRIBE `mail_virtual`");
$columnfound = 0;
while ($row = $result->fetch(PDO::FETCH_ASSOC)) {
if ($row['Field'] == 'description') {
$columnfound = 1;
}
}
if (! $columnfound) {
Database::query("ALTER TABLE mail_virtual ADD `description` varchar(255) NOT NULL DEFAULT '' AFTER `iscatchall`");
}
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103110');
}
if (\Froxlor\Froxlor::isDatabaseVersion('202103110')) {
showUpdateStep("Adding settings for imprint, terms of use and privacy policy URLs", true);
Settings::AddNew("panel.imprint_url", '');
Settings::AddNew("panel.terms_url", '');
Settings::AddNew("panel.privacy_url", '');
lastStepStatus(0);
\Froxlor\Froxlor::updateToDbVersion('202103240');
}
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` = '&#268;esk&aacute; 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');
}

View File

@@ -2505,7 +2505,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.30')) {
showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true); showUpdateStep("Updating from 0.9.30 to 0.9.31-dev1", true);
lastStepStatus(0); lastStepStatus(0);
showUpdateStep("Removing unsused tables"); showUpdateStep("Removing unused tables");
Database::query("DROP TABLE IF EXISTS `ipsandports_docrootsettings`;"); Database::query("DROP TABLE IF EXISTS `ipsandports_docrootsettings`;");
Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;"); Database::query("DROP TABLE IF EXISTS `domain_docrootsettings`;");
lastStepStatus(0); lastStepStatus(0);
@@ -2856,7 +2856,7 @@ if (\Froxlor\Froxlor::isFroxlorVersion('0.9.32-rc1')) {
Settings::AddNew("system.croncmdline", $croncmdline); Settings::AddNew("system.croncmdline", $croncmdline);
// add task to generate cron.d-file // add task to generate cron.d-file
\Froxlor\System\Cronjob::inserttask('99'); \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 // as it is a very dangerous setting
Settings::AddNew("system.cron_allowautoupdate", 0); Settings::AddNew("system.cron_allowautoupdate", 0);
lastStepStatus(0); lastStepStatus(0);
@@ -3872,7 +3872,7 @@ opcache.interned_strings_buffer');
if (\Froxlor\Froxlor::isDatabaseVersion('201801110')) { 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'); Settings::AddNew("phpfpm.envpath", '/usr/local/bin:/usr/bin:/bin');
lastStepStatus(0); lastStepStatus(0);

View File

@@ -19,7 +19,7 @@
* Function getPreConfig * Function getPreConfig
* *
* outputs various content before the update process * 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 string $current_version
* @param int $current_db_version * @param int $current_db_version
@@ -34,6 +34,9 @@ function getPreConfig($current_version, $current_db_version)
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php'); include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.9/preconfig_0.9.inc.php');
parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version); parseAndOutputPreconfig($has_preconfig, $return, $current_version, $current_db_version);
include_once \Froxlor\FileDir::makeCorrectFile(dirname(__FILE__) . '/preconfig/0.10/preconfig_0.10.inc.php');
parseAndOutputPreconfig2($has_preconfig, $return, $current_version, $current_db_version);
$return .= '<br /><br />' . \Froxlor\UI\HTML::makecheckbox('update_changesagreed', '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>', '1', true, '0', true); $return .= '<br /><br />' . \Froxlor\UI\HTML::makecheckbox('update_changesagreed', '<strong>I have read the update notifications above and I am aware of the changes made to my system.</strong>', '1', true, '0', true);
$return .= '</div>'; $return .= '</div>';
$return .= '<input type="hidden" name="update_preconfig" value="1" />'; $return .= '<input type="hidden" name="update_preconfig" value="1" />';

View File

@@ -0,0 +1,42 @@
<?php
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 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> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package Updater
*
*/
/**
* checks if the new-version has some updating to do
*
* @param boolean $has_preconfig
* pointer to check if any preconfig has to be output
* @param string $return
* pointer to output string
* @param string $current_version
* current froxlor version
*
* @return null
*/
function parseAndOutputPreconfig2(&$has_preconfig, &$return, $current_version, $current_db_version)
{
global $lng;
if (versionInUpdate($current_db_version, '202004140')) {
$has_preconfig = true;
$description = 'Froxlor can now optionally validate the dns entries of domains that request Lets Encrypt certificates to reduce dns-related problems (e.g. freshly registered domain or updated a-record).<br />';
$question = '<strong>Validate DNS of domains when using Lets Encrypt&nbsp;';
$question .= \Froxlor\UI\HTML::makeyesno('system_le_domain_dnscheck', '1', '0', '1');
eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";");
}
}

View File

@@ -414,7 +414,7 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
if (Settings::Get('system.webserver') == 'apache2') { if (Settings::Get('system.webserver') == 'apache2') {
$has_preconfig = true; $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 $description .= '<pre>LoadModule authz_core_module modules/mod_authz_core.so
LoadModule authz_host_module modules/mod_authz_host.so</pre><br />'; LoadModule authz_host_module modules/mod_authz_host.so</pre><br />';
$question = '<strong>Do you want to enable the Apache-2.4 modification?:</strong>&nbsp;'; $question = '<strong>Do you want to enable the Apache-2.4 modification?:</strong>&nbsp;';
@@ -600,8 +600,8 @@ function parseAndOutputPreconfig(&$has_preconfig, &$return, $current_version, $c
if (versionInUpdate($current_version, '0.9.32-rc2')) { if (versionInUpdate($current_version, '0.9.32-rc2')) {
$has_preconfig = true; $has_preconfig = true;
$description = 'To customize the command which executes the cronjob (php - basically) change the path below according to your system.<br /><br />'; $description = 'To customize the command which executes the cronjob (php - basically) change the path below according to your system.<br /><br />';
$question = '<strong>Please specify the command to execute cronscripts</strong> (default: "/usr/bin/nice -n 5 /usr/bin/php5 -q")<br />'; $question = '<strong>Please specify the command to execute cronscripts</strong> (default: "/usr/bin/nice -n 5 /usr/bin/php -q")<br />';
$question .= '<input type="text" class="text" name="croncmdline" value="/usr/bin/nice -n 5 /usr/bin/php5 -q" /><br />'; $question .= '<input type="text" class="text" name="croncmdline" value="/usr/bin/nice -n 5 /usr/bin/php -q" /><br />';
eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";"); eval("\$return.=\"" . \Froxlor\UI\Template::getTemplate("update/preconfigitem") . "\";");
} }

4
js/html5shiv.min.js vendored
View File

@@ -1,4 +1,4 @@
/** /**
* @preserve HTML5 Shiv 3.7.2 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed * @preserve HTML5 Shiv 3.7.3 | @afarkas @jdalton @jon_neal @rem | MIT/GPL2 Licensed
*/ */
!function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.2",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b)}(this,document); !function(a,b){function c(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x<style>"+b+"</style>",d.insertBefore(c.lastChild,d.firstChild)}function d(){var a=t.elements;return"string"==typeof a?a.split(" "):a}function e(a,b){var c=t.elements;"string"!=typeof c&&(c=c.join(" ")),"string"!=typeof a&&(a=a.join(" ")),t.elements=c+" "+a,j(b)}function f(a){var b=s[a[q]];return b||(b={},r++,a[q]=r,s[r]=b),b}function g(a,c,d){if(c||(c=b),l)return c.createElement(a);d||(d=f(c));var e;return e=d.cache[a]?d.cache[a].cloneNode():p.test(a)?(d.cache[a]=d.createElem(a)).cloneNode():d.createElem(a),!e.canHaveChildren||o.test(a)||e.tagUrn?e:d.frag.appendChild(e)}function h(a,c){if(a||(a=b),l)return a.createDocumentFragment();c=c||f(a);for(var e=c.frag.cloneNode(),g=0,h=d(),i=h.length;i>g;g++)e.createElement(h[g]);return e}function i(a,b){b.cache||(b.cache={},b.createElem=a.createElement,b.createFrag=a.createDocumentFragment,b.frag=b.createFrag()),a.createElement=function(c){return t.shivMethods?g(c,a,b):b.createElem(c)},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+d().join().replace(/[\w\-:]+/g,function(a){return b.createElem(a),b.frag.createElement(a),'c("'+a+'")'})+");return n}")(t,b.frag)}function j(a){a||(a=b);var d=f(a);return!t.shivCSS||k||d.hasCSS||(d.hasCSS=!!c(a,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||i(a,d),a}var k,l,m="3.7.3",n=a.html5||{},o=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,q="_html5shiv",r=0,s={};!function(){try{var a=b.createElement("a");a.innerHTML="<xyz></xyz>",k="hidden"in a,l=1==a.childNodes.length||function(){b.createElement("a");var a=b.createDocumentFragment();return"undefined"==typeof a.cloneNode||"undefined"==typeof a.createDocumentFragment||"undefined"==typeof a.createElement}()}catch(c){k=!0,l=!0}}();var t={elements:n.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:m,shivCSS:n.shivCSS!==!1,supportsUnknownElements:l,shivMethods:n.shivMethods!==!1,type:"default",shivDocument:j,createElement:g,createDocumentFragment:h,addElements:e};a.html5=t,j(b),"object"==typeof module&&module.exports&&(module.exports=t)}("undefined"!=typeof window?window:this,document);

4
js/jquery.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -54,6 +54,13 @@ abstract class ApiCommand extends ApiParameter
*/ */
private $mail = null; private $mail = null;
/**
* whether the call is an internal one or not
*
* @var boolean
*/
private $internal_call = false;
/** /**
* language strings array * language strings array
* *
@@ -90,10 +97,12 @@ abstract class ApiCommand extends ApiParameter
* optional, array of parameters (var=>value) for the command * optional, array of parameters (var=>value) for the command
* @param array $userinfo * @param array $userinfo
* optional, passed via WebInterface (instead of $header) * optional, passed via WebInterface (instead of $header)
* @param boolean $internal
* optional whether called internally, default false
* *
* @throws \Exception * @throws \Exception
*/ */
public function __construct($header = null, $params = null, $userinfo = null) public function __construct($header = null, $params = null, $userinfo = null, $internal = false)
{ {
parent::__construct($params); parent::__construct($params);
@@ -127,6 +136,9 @@ abstract class ApiCommand extends ApiParameter
if ($this->debug) { if ($this->debug) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES)); $this->logger()->logAction(\Froxlor\FroxlorLogger::LOG_ERROR, LOG_DEBUG, "[API] " . get_called_class() . ": " . json_encode($params, JSON_UNESCAPED_SLASHES));
} }
// set internal call flag
$this->internal_call = $internal;
} }
/** /**
@@ -191,13 +203,15 @@ abstract class ApiCommand extends ApiParameter
* array of user-data * array of user-data
* @param array $params * @param array $params
* array of parameters for the command * array of parameters for the command
* @param boolean $internal
* optional whether called internally, default false
* *
* @return ApiCommand * @return ApiCommand
* @throws \Exception * @throws \Exception
*/ */
public static function getLocal($userinfo = null, $params = null) public static function getLocal($userinfo = null, $params = null, $internal = false)
{ {
return new static(null, $params, $userinfo); return new static(null, $params, $userinfo, $internal);
} }
/** /**
@@ -210,6 +224,16 @@ abstract class ApiCommand extends ApiParameter
return $this->is_admin; return $this->is_admin;
} }
/**
* internal call flag
*
* @return boolean
*/
protected function isInternal()
{
return $this->internal_call;
}
/** /**
* return field from user-table * return field from user-table
* *
@@ -286,6 +310,13 @@ abstract class ApiCommand extends ApiParameter
} elseif (in_array($valoper['op'], $ops)) { } elseif (in_array($valoper['op'], $ops)) {
$condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield; $condition .= $field . ' ' . $valoper['op'] . ':' . $cleanfield;
$query_fields[':' . $cleanfield] = $valoper['value'] ?? ''; $query_fields[':' . $cleanfield] = $valoper['value'] ?? '';
} elseif (strtolower($valoper['op']) == 'in' && is_array($valoper['value']) && count($valoper['value']) > 0) {
$condition .= $field . ' ' . $valoper['op'] . ' (';
foreach ($valoper['value'] as $incnt => $invalue) {
$condition .= ":" . $cleanfield . $incnt . ", ";
$query_fields[':' . $cleanfield . $incnt] = $invalue ?? '';
}
$condition = substr($condition, 0, - 2) . ')';
} else { } else {
continue; continue;
} }
@@ -417,15 +448,18 @@ abstract class ApiCommand extends ApiParameter
* *
* @param string $command * @param string $command
* @param array|null $params * @param array|null $params
* @param boolean $internal
* optional whether called internally, default false
*
* *
* @return array * @return array
*/ */
protected function apiCall($command = null, $params = null) protected function apiCall($command = null, $params = null, $internal = false)
{ {
$_command = explode(".", $command); $_command = explode(".", $command);
$module = __NAMESPACE__ . "\Commands\\" . $_command[0]; $module = __NAMESPACE__ . "\Commands\\" . $_command[0];
$function = $_command[1]; $function = $_command[1];
$json_result = $module::getLocal($this->getUserData(), $params)->{$function}(); $json_result = $module::getLocal($this->getUserData(), $params, $internal)->{$function}();
return json_decode($json_result, true)['data']; return json_decode($json_result, true)['data'];
} }
@@ -491,7 +525,7 @@ abstract class ApiCommand extends ApiParameter
$customer_ids[] = $customer['customerid']; $customer_ids[] = $customer['customerid'];
} }
} else { } else {
if (! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) { if (! $this->isInternal() && ! empty($customer_hide_option) && \Froxlor\Settings::IsInList('panel.customer_hide_options', $customer_hide_option)) {
throw new \Exception("You cannot access this resource", 405); throw new \Exception("You cannot access this resource", 405);
} }
$customer_ids = array( $customer_ids = array(

View File

@@ -51,7 +51,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -75,7 +75,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_admins']); return $this->response(200, "successful", $result['num_admins']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -109,7 +109,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get admin '" . $result['loginname'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get admin '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'"); $key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Admin with " . $key . " could not be found", 404); throw new \Exception("Admin with " . $key . " could not be found", 404);
@@ -231,7 +231,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$idna_convert = new \Froxlor\Idna\IdnaWrapper(); $idna_convert = new \Froxlor\Idna\IdnaWrapper();
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true)); $email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true); $def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true); $custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (Settings::Get('system.mail_quota_enabled') != '1') { if (Settings::Get('system.mail_quota_enabled') != '1') {
$email_quota = - 1; $email_quota = - 1;
@@ -364,7 +364,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array( $result = $this->apiCall('Admins.get', array(
'id' => $adminid 'id' => $adminid
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -531,7 +531,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$idna_convert = new \Froxlor\Idna\IdnaWrapper(); $idna_convert = new \Froxlor\Idna\IdnaWrapper();
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true)); $email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true); $def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true); $custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$theme = \Froxlor\Validate\Validate::validate($theme, 'theme', '', '', array(), true); $theme = \Froxlor\Validate\Validate::validate($theme, 'theme', '', '', array(), true);
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
@@ -677,7 +677,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Admins.get', array( $result = $this->apiCall('Admins.get', array(
'id' => $result['adminid'] 'id' => $result['adminid']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }
} }
@@ -713,6 +713,10 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
if ($id == $this->getUserDetail('adminid')) { if ($id == $this->getUserDetail('adminid')) {
\Froxlor\UI\Response::standard_error('youcantdeleteyourself', '', true); \Froxlor\UI\Response::standard_error('youcantdeleteyourself', '', true);
} }
// can't delete the first superadmin
if ($id == 1) {
\Froxlor\UI\Response::standard_error('cannotdeletesuperadmin', '', true);
}
// delete admin // delete admin
$del_stmt = Database::prepare(" $del_stmt = Database::prepare("
@@ -730,14 +734,6 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
'adminid' => $id 'adminid' => $id
), true, true); ), true, true);
// delete the diskspace usage
$del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_DISKSPACE_ADMINS . "` WHERE `adminid` = :adminid
");
Database::pexecute($del_stmt, array(
'adminid' => $id
), true, true);
// set admin-id of the old admin's customer to current admins // set admin-id of the old admin's customer to current admins
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET UPDATE `" . TABLE_PANEL_CUSTOMERS . "` SET
@@ -779,7 +775,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted admin '" . $result['loginname'] . "'");
\Froxlor\User::updateCounters(); \Froxlor\User::updateCounters();
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -821,7 +817,7 @@ class Admins extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result['loginfail_count'] = 0; $result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked admin '" . $result['loginname'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked admin '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -0,0 +1,30 @@
<?php
namespace Froxlor\Api\Commands;
use Froxlor\Database\Database;
use Froxlor\Settings;
/**
* This file is part of the Froxlor project.
* Copyright (c) 2010 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> (2010-)
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
* @package API
* @since 0.10.0
*
*/
class ApiKeys extends \Froxlor\Api\ApiCommand
{
public function listing()
{}
public function listingCount()
{}
}

View File

@@ -81,7 +81,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array( $result = $this->apiCall('Certificates.get', array(
'id' => $domain['id'] 'id' => $domain['id']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Domain '" . $domain['domain'] . "' already has a certificate. Did you mean to call update?", 406); throw new \Exception("Domain '" . $domain['domain'] . "' already has a certificate. Did you mean to call update?", 406);
} }
@@ -122,7 +122,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
if (! $result) { if (! $result) {
throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412); throw new \Exception("Domain '" . $domain['domain'] . "' does not have a certificate.", 412);
} }
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -168,7 +168,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('Certificates.get', array( $result = $this->apiCall('Certificates.get', array(
'id' => $domain['id'] 'id' => $domain['id']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -189,7 +189,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
*/ */
public function listing() 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 $certs_stmt_query = "SELECT s.*, d.domain, d.letsencrypt, c.customerid, c.loginname
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
@@ -222,7 +222,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} }
$result[] = $cert; $result[] = $cert;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -237,7 +237,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
*/ */
public function listingCount() public function listingCount()
{ {
// select all my (accessable) certificates // select all my (accessible) certificates
$certs_stmt_query = "SELECT COUNT(*) as num_certs $certs_stmt_query = "SELECT COUNT(*) as num_certs
FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` s
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON `d`.`id` = `s`.`domainid`
@@ -258,7 +258,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$certs_stmt = Database::prepare($certs_stmt_query); $certs_stmt = Database::prepare($certs_stmt_query);
$result = Database::pexecute_first($certs_stmt, $qry_params, true, true); $result = Database::pexecute_first($certs_stmt, $qry_params, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_certs']); return $this->response(200, "successful", $result['num_certs']);
} }
} }
@@ -323,10 +323,10 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
)); ));
// trigger removing of certificate from acme.sh if let's encrypt // trigger removing of certificate from acme.sh if let's encrypt
if ($chk['letsencrypt'] == '1') { 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'] . "'"); $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, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406); throw new \Exception("Unable to determine SSL certificate. Maybe no access?", 406);
} }
@@ -421,7 +421,7 @@ class Certificates extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
// insert task to re-generate webserver-configs (#1260) // insert task to re-generate webserver-configs (#1260)
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
return true; return true;
} }
} }

View File

@@ -51,7 +51,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
'id' => $id 'id' => $id
), true, true); ), true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("cronjob with id #" . $id . " could not be found", 404); throw new \Exception("cronjob with id #" . $id . " could not be found", 404);
} }
@@ -114,12 +114,12 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
), true, true); ), true, true);
// insert task to re-generate the cron.d-file // 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') . "'"); $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( $result = $this->apiCall('Cronjobs.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -152,7 +152,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -175,7 +175,7 @@ class Cronjobs extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceE
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_crons']); return $this->response(200, "successful", $result['num_crons']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);

View File

@@ -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 * @throws \Exception
*/ */
@@ -52,7 +52,9 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param bool $backup_web * @param bool $backup_web
* optional whether to backup web-data, default is 0 (false) * optional whether to backup web-data, default is 0 (false)
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -106,10 +108,10 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
'backup_web' => $backup_web 'backup_web' => $backup_web
); );
// schedule backup job // 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); $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, "successfull", $task_data); return $this->response(200, "successful", $task_data);
} }
/** /**
@@ -168,7 +170,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
} }
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list customer-backups"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list customer-backups");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -202,7 +204,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result_count ++; $result_count ++;
} }
} }
return $this->response(200, "successfull", $result_count); return $this->response(200, "successful", $result_count);
} }
/** /**
@@ -237,7 +239,7 @@ class CustomerBackups extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
'tid' => $entry 'tid' => $entry
), true, true); ), true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] deleted planned customer-backup #" . $entry);
return $this->response(200, "successfull", true); return $this->response(200, "successful", true);
} }
} }
} }

View File

@@ -33,6 +33,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional specify offset for resultset * optional specify offset for resultset
* @param array $sql_orderby * @param array $sql_orderby
* optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields * optional array with index = fieldname and value = ASC|DESC to order the resultset by one or more fields
* @param bool $show_usages
* optional, default false
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
@@ -41,6 +43,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
public function listing() public function listing()
{ {
if ($this->isAdmin()) { if ($this->isAdmin()) {
$show_usages = $this->getBoolParam('show_usages', true, false);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] list customers");
$query_fields = array(); $query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
@@ -57,10 +60,50 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$params = array_merge($params, $query_fields); $params = array_merge($params, $query_fields);
Database::pexecute($result_stmt, $params, true, true); Database::pexecute($result_stmt, $params, true, true);
$result = array(); $result = array();
$domains_stmt = null;
$usages_stmt = null;
if ($show_usages) {
$domains_stmt = Database::prepare("
SELECT COUNT(`id`) AS `domains`
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :cid
AND `parentdomainid` = '0'
AND `id`<> :stdd
");
$usages_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
WHERE `customerid` = :cid
ORDER BY `stamp` DESC LIMIT 1
");
}
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
if ($show_usages) {
// get number of domains
Database::pexecute($domains_stmt, array(
'cid' => $row['customerid'],
'stdd' => $row['standardsubdomain']
));
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
$row['domains'] = intval($domains['domains']);
// get disk-space usages for web, mysql and mail
$usages = Database::pexecute_first($usages_stmt, array(
'cid' => $row['customerid']
));
if ($usages) {
$row['webspace_used'] = $usages['webspace'];
$row['mailspace_used'] = $usages['mail'];
$row['dbspace_used'] = $usages['mysql'];
} else {
$row['webspace_used'] = 0;
$row['mailspace_used'] = 0;
$row['dbspace_used'] = 0;
}
}
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -90,7 +133,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
} }
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_customers']); return $this->response(200, "successful", $result['num_customers']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -103,6 +146,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional, the customer-id * optional, the customer-id
* @param string $loginname * @param string $loginname
* optional, the loginname * optional, the loginname
* @param bool $show_usages
* optional, default false
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -113,6 +158,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$id = $this->getParam('id', true, 0); $id = $this->getParam('id', true, 0);
$ln_optional = ($id <= 0 ? false : true); $ln_optional = ($id <= 0 ? false : true);
$loginname = $this->getParam('loginname', $ln_optional, ''); $loginname = $this->getParam('loginname', $ln_optional, '');
$show_usages = $this->getBoolParam('show_usages', true, false);
if ($this->isAdmin()) { if ($this->isAdmin()) {
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
@@ -142,8 +188,42 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
if (! $this->isAdmin() && $result['custom_notes_show'] != 1) { if (! $this->isAdmin() && $result['custom_notes_show'] != 1) {
$result['custom_notes'] = ""; $result['custom_notes'] = "";
} }
if ($show_usages) {
// get number of domains
$domains_stmt = Database::prepare("
SELECT COUNT(`id`) AS `domains`
FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `customerid` = :cid
AND `parentdomainid` = '0'
AND `id`<> :stdd
");
Database::pexecute($domains_stmt, array(
'cid' => $result['customerid'],
'stdd' => $result['standardsubdomain']
));
$domains = $domains_stmt->fetch(\PDO::FETCH_ASSOC);
$result['domains'] = intval($domains['domains']);
// get disk-space usages for web, mysql and mail
$usages_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_DISKSPACE . "`
WHERE `customerid` = :cid
ORDER BY `stamp` DESC LIMIT 1
");
$usages = Database::pexecute_first($usages_stmt, array(
'cid' => $result['customerid']
));
if ($usages) {
$result['webspace_used'] = $usages['webspace'];
$result['mailspace_used'] = $usages['mail'];
$result['dbspace_used'] = $usages['mysql'];
} else {
$result['webspace_used'] = 0;
$result['mailspace_used'] = 0;
$result['dbspace_used'] = 0;
}
}
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'"); $key = ($id > 0 ? "id #" . $id : "loginname '" . $loginname . "'");
throw new \Exception("Customer with " . $key . " could not be found", 404); throw new \Exception("Customer with " . $key . " could not be found", 404);
@@ -183,7 +263,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* optional, whether to show the content of custom_notes to the customer, default 0 (false) * optional, whether to show the content of custom_notes to the customer, default 0 (false)
* @param string $new_loginname * @param string $new_loginname
* optional, if empty generated automatically using customer-prefix and increasing number * optional, if empty generated automatically using customer-prefix and increasing number
* @param string $password * @param string $new_customer_password
* optional, if empty generated automatically and send to the customer's email if $sendpassword is 1 * optional, if empty generated automatically and send to the customer's email if $sendpassword is 1
* @param bool $sendpassword * @param bool $sendpassword
* optional, whether to send the password to the customer after creation, default 0 (false) * optional, whether to send the password to the customer after creation, default 0 (false)
@@ -228,7 +308,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* @param bool $mysqls_ul * @param bool $mysqls_ul
* optional, whether customer should have unlimited mysql-databases, default 0 (false) * optional, whether customer should have unlimited mysql-databases, default 0 (false)
* @param bool $createstdsubdomain * @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 * @param bool $phpenabled
* optional, whether to allow usage of PHP, default 0 (false) * optional, whether to allow usage of PHP, default 0 (false)
* @param array $allowed_phpconfigs * @param array $allowed_phpconfigs
@@ -236,9 +316,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* @param bool $perlenabled * @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false) * optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled * @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 * @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 * @param bool $store_defaultindex
* optional, whether to store the default index file to customers homedir * optional, whether to store the default index file to customers homedir
* @param int $hosting_plan_id * @param int $hosting_plan_id
@@ -272,7 +352,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$gender = (int) $this->getParam('gender', true, 0); $gender = (int) $this->getParam('gender', true, 0);
$custom_notes = $this->getParam('custom_notes', true, ''); $custom_notes = $this->getParam('custom_notes', true, '');
$custom_notes_show = $this->getBoolParam('custom_notes_show', true, 0); $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, ''); $password = $this->getParam('new_customer_password', true, '');
$sendpassword = $this->getBoolParam('sendpassword', true, 0); $sendpassword = $this->getBoolParam('sendpassword', true, 0);
$store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0); $store_defaultindex = $this->getBoolParam('store_defaultindex', true, 0);
@@ -336,7 +416,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true)); $email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true); $customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true);
$def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true); $def_language = \Froxlor\Validate\Validate::validate($def_language, 'default language', '', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true); $custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (Settings::Get('system.mail_quota_enabled') != '1') { if (Settings::Get('system.mail_quota_enabled') != '1') {
$email_quota = - 1; $email_quota = - 1;
@@ -565,10 +645,10 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
unset($ins_data); unset($ins_data);
// insert task to create homedir etc. // 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 // 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 // Add htpasswd for the stats-pages
$htpasswdPassword = \Froxlor\System\Crypt::makeCryptPassword($password, true); $htpasswdPassword = \Froxlor\System\Crypt::makeCryptPassword($password, true);
@@ -594,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 . "'"); $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); 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 // add default FTP-User
// also, add froxlor-local user to ftp-group (if exists!) to // also, add froxlor-local user to ftp-group (if exists!) to
@@ -659,7 +739,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'customerid' => $customerid 'customerid' => $customerid
), true, true); ), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $loginname . "'"); $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);
} }
} }
@@ -689,6 +769,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'name' => $name, 'name' => $name,
'company' => $company 'company' => $company
)), )),
'CUSTOMER_NO' => $customernumber,
'USERNAME' => $loginname, 'USERNAME' => $loginname,
'PASSWORD' => $password, 'PASSWORD' => $password,
'SERVER_HOSTNAME' => $srv_hostname, 'SERVER_HOSTNAME' => $srv_hostname,
@@ -742,7 +823,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array( $result = $this->apiCall('Customers.get', array(
'loginname' => $loginname 'loginname' => $loginname
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
} }
@@ -834,7 +915,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* @param bool $mysqls_ul * @param bool $mysqls_ul
* optional, whether customer should have unlimited mysql-databases, default 0 (false) * optional, whether customer should have unlimited mysql-databases, default 0 (false)
* @param bool $createstdsubdomain * @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 * @param bool $phpenabled
* optional, whether to allow usage of PHP, default 0 (false) * optional, whether to allow usage of PHP, default 0 (false)
* @param array $allowed_phpconfigs * @param array $allowed_phpconfigs
@@ -842,9 +923,9 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
* @param bool $perlenabled * @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false) * optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled * @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 * @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 * @param string $theme
* optional, change theme * optional, change theme
* *
@@ -872,7 +953,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email = $this->getParam('email', true, $idna_convert->decode($result['email'])); $email = $this->getParam('email', true, $idna_convert->decode($result['email']));
$name = $this->getParam('name', true, $result['name']); $name = $this->getParam('name', true, $result['name']);
$firstname = $this->getParam('firstname', true, $result['firstname']); $firstname = $this->getParam('firstname', true, $result['firstname']);
$company_required = (! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname)); $company_required = empty($result['company']) && ((! empty($name) && empty($firstname)) || (empty($name) && ! empty($firstname)) || (empty($name) && empty($firstname)));
$company = $this->getParam('company', ($company_required ? false : true), $result['company']); $company = $this->getParam('company', ($company_required ? false : true), $result['company']);
$street = $this->getParam('street', true, $result['street']); $street = $this->getParam('street', true, $result['street']);
$zipcode = $this->getParam('zipcode', true, $result['zipcode']); $zipcode = $this->getParam('zipcode', true, $result['zipcode']);
@@ -898,7 +979,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$email_pop3 = $this->getParam('email_pop3', true, $result['pop3']); $email_pop3 = $this->getParam('email_pop3', true, $result['pop3']);
$ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']); $ftps = $this->getUlParam('ftps', 'ftps_ul', true, $result['ftps']);
$mysqls = $this->getUlParam('mysqls', 'mysqls_ul', true, $result['mysqls']); $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, ''); $password = $this->getParam('new_customer_password', true, '');
$phpenabled = $this->getBoolParam('phpenabled', true, $result['phpenabled']); $phpenabled = $this->getBoolParam('phpenabled', true, $result['phpenabled']);
$allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true)); $allowed_phpconfigs = $this->getParam('allowed_phpconfigs', true, json_decode($result['allowed_phpconfigs'], true));
@@ -927,7 +1008,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$fax = \Froxlor\Validate\Validate::validate($fax, 'fax', '/^[0-9\- \+\(\)\/]*$/', '', array(), true); $fax = \Froxlor\Validate\Validate::validate($fax, 'fax', '/^[0-9\- \+\(\)\/]*$/', '', array(), true);
$email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true)); $email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($email, 'email', '', '', array(), true));
$customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true); $customernumber = \Froxlor\Validate\Validate::validate($customernumber, 'customer number', '/^[A-Za-z0-9 \-]*$/Di', '', array(), true);
$custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', '/^[^\0]*$/', '', array(), true); $custom_notes = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $custom_notes), 'custom_notes', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
if (! empty($allowed_phpconfigs)) { if (! empty($allowed_phpconfigs)) {
$allowed_phpconfigs = array_map('intval', $allowed_phpconfigs); $allowed_phpconfigs = array_map('intval', $allowed_phpconfigs);
} }
@@ -970,7 +1051,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
} }
if ($this->isAdmin()) { if ($this->isAdmin()) {
if ($createstdsubdomain != '1') { if ($createstdsubdomain != '1' || $deactivated) {
$createstdsubdomain = '0'; $createstdsubdomain = '0';
} }
@@ -1007,7 +1088,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'customerid' => $result['customerid'] 'customerid' => $result['customerid']
), true, true); ), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] automatically added standardsubdomain for user '" . $result['loginname'] . "'"); $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);
} }
} }
@@ -1021,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_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'] . "'"); $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']) { 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 // activate/deactivate customer services
@@ -1111,7 +1192,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
), true, true); ), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] " . ($deactivated ? 'deactivated' : 'reactivated') . " user '" . $result['loginname'] . "'"); $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 // Disable or enable POP3 Login for customers Mail Accounts
@@ -1223,7 +1304,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
if ($this->isAdmin()) { if ($this->isAdmin()) {
// Using filesystem - quota, insert a task which cleans the filesystem - quota // 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` "; $admin_update_query = "UPDATE `" . TABLE_PANEL_ADMINS . "` SET `customers_used` = `customers_used` ";
@@ -1339,7 +1420,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array( $result = $this->apiCall('Customers.get', array(
'id' => $result['customerid'] 'id' => $result['customerid']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -1409,8 +1490,8 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
'id' => $id 'id' => $id
), true, true); ), true, true);
// first gather all domain-id's to clean up panel_domaintoip and dns-entries accordingly // first gather all domain-id's to clean up panel_domaintoip, dns-entries and certificates accordingly
$did_stmt = Database::prepare("SELECT `id` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id"); $did_stmt = Database::prepare("SELECT `id`, `domain` FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
Database::pexecute($did_stmt, array( Database::pexecute($did_stmt, array(
'id' => $id 'id' => $id
), true, true); ), true, true);
@@ -1425,6 +1506,15 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
Database::pexecute($stmt, array( Database::pexecute($stmt, array(
'did' => $row['id'] 'did' => $row['id']
), true, true); ), true, true);
// remove domain->certificates entries
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAIN_SSL_SETTINGS . "` WHERE `domainid` = :did");
Database::pexecute($stmt, array(
'did' => $row['id']
), true, true);
// remove domains DNS from powerDNS if used, #581
\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(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $row['domain']);
} }
// remove customer domains // remove customer domains
$stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id"); $stmt = Database::prepare("DELETE FROM `" . TABLE_PANEL_DOMAINS . "` WHERE `customerid` = :id");
@@ -1553,21 +1643,21 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
} }
// rebuild configs // 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 // 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) { if ($delete_userfiles == 1) {
// insert task to remove the customers files from the filesystem // 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 // 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'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -1609,7 +1699,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result['loginfail_count'] = 0; $result['loginfail_count'] = 0;
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked customer '" . $result['loginname'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] unlocked customer '" . $result['loginname'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -1679,7 +1769,7 @@ class Customers extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resource
$result = $this->apiCall('Customers.get', array( $result = $this->apiCall('Customers.get', array(
'id' => $c_result['customerid'] 'id' => $c_result['customerid']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -26,9 +26,9 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* add options for a given directory * add options for a given directory
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $path * @param string $path
* path relative to the customer's home-Directory * path relative to the customer's home-Directory
* @param bool $options_indexes * @param bool $options_indexes
@@ -69,7 +69,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$error500path = $this->getParam('error500path', true, ''); $error500path = $this->getParam('error500path', true, '');
// validation // validation
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', '', '', array(), true)); $path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true));
$userpath = $path; $userpath = $path;
$path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path); $path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path);
@@ -123,12 +123,12 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
$id = Database::lastInsertId(); $id = Database::lastInsertId();
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] added directory-option for '" . $userpath . "'"); $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( $result = $this->apiCall('DirOptions.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -186,7 +186,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory options for '" . $result['path'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory options for '" . $result['path'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = "id #" . $id; $key = "id #" . $id;
throw new \Exception("Directory option with " . $key . " could not be found", 404); throw new \Exception("Directory option with " . $key . " could not be found", 404);
@@ -198,9 +198,9 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param int $id * @param int $id
* id of dir-protection entry * id of dir-protection entry
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param bool $options_indexes * @param bool $options_indexes
* optional, activate directory-listing for this path, default 0 (false) * optional, activate directory-listing for this path, default 0 (false)
* @param bool $options_cgi * @param bool $options_cgi
@@ -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'])) { 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(" $stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_HTACCESS . "` UPDATE `" . TABLE_PANEL_HTACCESS . "`
SET `options_indexes` = :options_indexes, SET `options_indexes` = :options_indexes,
@@ -275,7 +275,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('DirOptions.get', array( $result = $this->apiCall('DirOptions.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -315,14 +315,14 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-options"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-options");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable directory options * returns the total number of accessible directory options
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select directory-protections of a specific customer by id * optional, admin-only, select directory-protections of a specific customer by id
@@ -347,7 +347,7 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_htaccess']); return $this->response(200, "successful", $result['num_htaccess']);
} }
} }
@@ -413,8 +413,8 @@ class DirOptions extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"id" => $id "id" => $id
), true, true); ), 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']) . "'"); $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, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**

View File

@@ -26,9 +26,9 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* add htaccess protection to a given directory * add htaccess protection to a given directory
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $path * @param string $path
* @param string $username * @param string $username
* @param string $directory_password * @param string $directory_password
@@ -60,7 +60,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$authname = $this->getParam('directory_authname', true, ''); $authname = $this->getParam('directory_authname', true, '');
// validation // validation
$path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', '', '', array(), true)); $path = \Froxlor\FileDir::makeCorrectDir(\Froxlor\Validate\Validate::validate($path, 'path', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true));
$path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path); $path = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . '/' . $path);
$username = \Froxlor\Validate\Validate::validate($username, 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/', '', array(), true); $username = \Froxlor\Validate\Validate::validate($username, 'username', '/^[a-zA-Z0-9][a-zA-Z0-9\-_]+\$?$/', '', array(), true);
$authname = \Froxlor\Validate\Validate::validate($authname, 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/', '', array(), true); $authname = \Froxlor\Validate\Validate::validate($authname, 'directory_authname', '/^[a-zA-Z0-9][a-zA-Z0-9\-_ ]+\$?$/', '', array(), true);
@@ -106,12 +106,12 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
$id = Database::lastInsertId(); $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 . ")'"); $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( $result = $this->apiCall('DirProtections.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -173,7 +173,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory protection for '" . $result['path'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get directory protection for '" . $result['path'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'"); $key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("Directory protection with " . $key . " could not be found", 404); throw new \Exception("Directory protection with " . $key . " could not be found", 404);
@@ -187,9 +187,9 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
* @param string $username * @param string $username
* optional, the username * optional, the username
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $directory_password * @param string $directory_password
* optional, leave empty for no change * optional, leave empty for no change
* @param string $directory_authname * @param string $directory_authname
@@ -251,14 +251,14 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid UPDATE `" . TABLE_PANEL_HTPASSWDS . "` SET " . $upd_query . " WHERE `id` = :id AND `customerid`= :cid
"); ");
Database::pexecute($upd_stmt, $upd_params, true, true); 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'] . ")'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] updated directory-protection '" . $result['username'] . " (" . $result['path'] . ")'");
$result = $this->apiCall('DirProtections.get', array( $result = $this->apiCall('DirProtections.get', array(
'id' => $result['id'] 'id' => $result['id']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -298,14 +298,14 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-protections"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list directory-protections");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable directory protections * returns the total number of accessible directory protections
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select directory-protections of a specific customer by id * optional, admin-only, select directory-protections of a specific customer by id
@@ -330,7 +330,7 @@ class DirProtections extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Res
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_htpasswd']); return $this->response(200, "successful", $result['num_htpasswd']);
} }
} }
@@ -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'] . ")'"); $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, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }

View File

@@ -136,8 +136,24 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
// types // types
if ($type == 'A' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) { if ($type == 'A' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false) {
$errors[] = $this->lng['error']['dns_arec_noipv4']; $errors[] = $this->lng['error']['dns_arec_noipv4'];
} elseif ($type == 'A') {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
} elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) { } elseif ($type == 'AAAA' && filter_var($content, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
$errors[] = $this->lng['error']['dns_aaaarec_noipv6']; $errors[] = $this->lng['error']['dns_aaaarec_noipv6'];
} elseif ($type == 'AAAA') {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
} elseif ($type == 'CAA' && ! empty($content)) { } elseif ($type == 'CAA' && ! empty($content)) {
$re = '/(?\'critical\'\d)\h*(?\'type\'iodef|issue|issuewild)\h*(?\'value\'(?\'issuevalue\'"(?\'domain\'(?=.{3,128}$)(?>(?>[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)*(?>[a-zA-Z]{2,}|[a-zA-Z0-9]{2,}\.[a-zA-Z]{2,}))[;\h]*(?\'parameters\'(?>[a-zA-Z0-9]{1,60}=[a-zA-Z0-9]{1,60}\h*)+)?")|(?\'iodefvalue\'"(?\'url\'(mailto:.*|http:\/\/.*|https:\/\/.*))"))/'; $re = '/(?\'critical\'\d)\h*(?\'type\'iodef|issue|issuewild)\h*(?\'value\'(?\'issuevalue\'"(?\'domain\'(?=.{3,128}$)(?>(?>[a-zA-Z0-9]+[a-zA-Z0-9-]*[a-zA-Z0-9]+|[a-zA-Z0-9]+)\.)*(?>[a-zA-Z]{2,}|[a-zA-Z0-9]{2,}\.[a-zA-Z]{2,}))[;\h]*(?\'parameters\'(?>[a-zA-Z0-9]{1,60}=[a-zA-Z0-9]{1,60}\h*)+)?")|(?\'iodefvalue\'"(?\'url\'(mailto:.*|http:\/\/.*|https:\/\/.*))"))/';
preg_match($re, $content, $matches); preg_match($re, $content, $matches);
@@ -170,6 +186,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
break; break;
} }
} }
// check www-alias setting
if ($result['wwwserveralias'] == '1' && $result['iswildcarddomain'] == '0' && $record == 'www') {
$errors[] = $this->lng['error']['no_wwwcnamae_ifwwwalias'];
}
} }
// append trailing dot (again) // append trailing dot (again)
$content .= '.'; $content .= '.';
@@ -194,6 +214,10 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$errors[] = $this->lng['error']['dns_mx_noalias']; $errors[] = $this->lng['error']['dns_mx_noalias'];
break; break;
} }
elseif ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
} }
} }
// append trailing dot (again) // append trailing dot (again)
@@ -206,6 +230,14 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
} }
if (! \Froxlor\Validate\Validate::validateDomain($content)) { if (! \Froxlor\Validate\Validate::validateDomain($content)) {
$errors[] = $this->lng['error']['dns_ns_invaliddom']; $errors[] = $this->lng['error']['dns_ns_invaliddom'];
} else {
// check whether there is a CNAME-record for the same resource
foreach ($dom_entries as $existing_entries) {
if ($existing_entries['type'] == 'CNAME' && $existing_entries['record'] == $record) {
$errors[] = $this->lng['error']['dns_other_nomorerr'];
break;
}
}
} }
// append trailing dot (again) // append trailing dot (again)
$content .= '.'; $content .= '.';
@@ -304,15 +336,15 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$dom_entries[] = $new_entry; $dom_entries[] = $new_entry;
// re-generate bind configs // re-generate bind configs
\Froxlor\System\Cronjob::inserttask('4'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
$result = $this->apiCall('DomainZones.get', array( $result = $this->apiCall('DomainZones.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
// return $errors // return $errors
throw new \Exception(implode("\n", $errors)); throw new \Exception(implode("\n", $errors), 406);
} }
/** /**
@@ -360,7 +392,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$zonefile = (string) $zone; $zonefile = (string) $zone;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get dns-zone for '" . $result['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get dns-zone for '" . $result['domain'] . "'");
return $this->response(200, "successfull", explode("\n", $zonefile)); return $this->response(200, "successful", explode("\n", $zonefile));
} }
/** /**
@@ -420,7 +452,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $sel_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -464,7 +496,7 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'did' => $id 'did' => $id
), true, true); ), true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_dns']); return $this->response(200, "successful", $result['num_dns']);
} }
} }
@@ -510,9 +542,9 @@ class DomainZones extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
), true, true); ), true, true);
if ($del_stmt->rowCount() > 0) { if ($del_stmt->rowCount() > 0) {
// re-generate bind configs // re-generate bind configs
\Froxlor\System\Cronjob::inserttask('4'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
return $this->response(200, "successfull", true); return $this->response(200, "successful", true);
} }
return $this->response(304, "successfull", true); return $this->response(304, "successful", true);
} }
} }

View File

@@ -68,7 +68,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -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 * @access admin
* @throws \Exception * @throws \Exception
@@ -100,7 +100,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_domains']); return $this->response(200, "successful", $result['num_domains']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -156,7 +156,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result['ipsandports'] = $this->getIpsForDomain($result['id']); $result['ipsandports'] = $this->getIpsForDomain($result['id']);
} }
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get domain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'"); $key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Domain with " . $key . " could not be found", 404); throw new \Exception("Domain with " . $key . " could not be found", 404);
@@ -193,12 +193,36 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
return $ipandports; 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 * add new domain entry
* *
* @param string $domain * @param string $domain
* domain-name * domain-name
* @param int $customerid * @param int $customerid
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* @param int $adminid * @param int $adminid
* optional, default is the calling admin's ID * optional, default is the calling admin's ID
* @param array $ipandport * @param array $ipandport
@@ -210,12 +234,12 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param bool $email_only * @param bool $email_only
* optional, restrict domain to email usage, default 0 (false) * optional, restrict domain to email usage, default 0 (false)
* @param int $selectserveralias * @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 * @param bool $speciallogfile
* optional, whether to create an exclusive web-logfile for this domain, default 0 (false) * optional, whether to create an exclusive web-logfile for this domain, default 0 (false)
* @param int $alias * @param int $alias
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none) * 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) * 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 * @param string $registration_date
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none) * optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
@@ -285,6 +309,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true * optional list of allowed/used ssl/tls ciphers, see system.ssl_cipher_list setting, only used/required if $override_tls is true, default empty or system.ssl_cipher_list setting if $override_tls is true
* @param string $tlsv13_cipher_list * @param string $tlsv13_cipher_list
* optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true * optional list of allowed/used tls-1.3 specific ciphers, see system.tlsv13_cipher_list setting, only used/required if $override_tls is true, default empty or system.tlsv13_cipher_list setting if $override_tls is true
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
@@ -297,7 +323,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// parameters // parameters
$p_domain = $this->getParam('domain'); $p_domain = $this->getParam('domain');
$customerid = intval($this->getParam('customerid'));
// optional parameters // optional parameters
$p_ipandports = $this->getParam('ipandport', true, explode(',', Settings::Get('system.defaultip'))); $p_ipandports = $this->getParam('ipandport', true, explode(',', Settings::Get('system.defaultip')));
@@ -305,7 +330,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$subcanemaildomain = $this->getParam('subcanemaildomain', true, 0); $subcanemaildomain = $this->getParam('subcanemaildomain', true, 0);
$isemaildomain = $this->getBoolParam('isemaildomain', true, 0); $isemaildomain = $this->getBoolParam('isemaildomain', true, 0);
$email_only = $this->getBoolParam('email_only', 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); $speciallogfile = $this->getBoolParam('speciallogfile', true, 0);
$aliasdomain = intval($this->getParam('alias', true, 0)); $aliasdomain = intval($this->getParam('alias', true, 0));
$issubof = $this->getParam('issubof', true, 0); $issubof = $this->getParam('issubof', true, 0);
@@ -352,6 +377,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list')); $tlsv13_cipher_list = $this->getParam('tlsv13_cipher_list', true, Settings::Get('system.tlsv13_cipher_list'));
} }
} }
$description = $this->getParam('description', true, '');
// validation // validation
$p_domain = strtolower($p_domain); $p_domain = strtolower($p_domain);
@@ -377,9 +403,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
), '', true); ), '', true);
} }
$customer = $this->apiCall('Customers.get', array( $customer = $this->getCustomerData();
'id' => $customerid $customerid = $customer['customerid'];
));
if ($this->getUserDetail('customers_see_all') == '1' && $adminid != $this->getUserDetail('adminid')) { if ($this->getUserDetail('customers_see_all') == '1' && $adminid != $this->getUserDetail('adminid')) {
$admin_stmt = Database::prepare(" $admin_stmt = Database::prepare("
@@ -402,6 +427,20 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
$_documentroot = \Froxlor\FileDir::makeCorrectDir($customer['documentroot'] . $path_suffix); $_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( $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', '0000-00-00',
'0', '0',
@@ -428,18 +467,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$zonefile = ''; $zonefile = '';
} }
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', '/^[^\0]*$/', '', array(), true); $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', '', '', 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(); $ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) { if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
@@ -482,7 +510,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$notryfiles = '0'; $notryfiles = '0';
$writeaccesslog = '1'; $writeaccesslog = '1';
$writeerrorlog = '1'; $writeerrorlog = '1';
$documentroot = $_documentroot;
$override_tls = '0'; $override_tls = '0';
$ssl_protocols = array(); $ssl_protocols = array();
} }
@@ -570,6 +597,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$include_specialsettings = 0; $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 // We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1') { if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true); \Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
@@ -684,6 +720,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ins_data = array( $ins_data = array(
'domain' => $domain, 'domain' => $domain,
'domain_ace' => $idna_convert->decode($domain),
'customerid' => $customerid, 'customerid' => $customerid,
'adminid' => $adminid, 'adminid' => $adminid,
'documentroot' => $documentroot, 'documentroot' => $documentroot,
@@ -726,12 +763,14 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
'tlsv13_cipher_list' => $tlsv13_cipher_list, 'tlsv13_cipher_list' => $tlsv13_cipher_list,
'sslenabled' => $sslenabled, 'sslenabled' => $sslenabled,
'honorcipherorder' => $honorcipherorder, 'honorcipherorder' => $honorcipherorder,
'sessiontickets' => $sessiontickets 'sessiontickets' => $sessiontickets,
'description' => $description
); );
$ins_stmt = Database::prepare(" $ins_stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
`domain` = :domain, `domain` = :domain,
`domain_ace` = :domain_ace,
`customerid` = :customerid, `customerid` = :customerid,
`adminid` = :adminid, `adminid` = :adminid,
`documentroot` = :documentroot, `documentroot` = :documentroot,
@@ -777,7 +816,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`tlsv13_cipher_list` = :tlsv13_cipher_list, `tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled, `ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder, `ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets`= :sessiontickets `ssl_sessiontickets` = :sessiontickets,
`description` = :description
"); ");
Database::pexecute($ins_stmt, $ins_data, true, true); Database::pexecute($ins_stmt, $ins_data, true, true);
$domainid = Database::lastInsertId(); $domainid = Database::lastInsertId();
@@ -817,16 +857,16 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($aliasdomain, $this->logger()); \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 // 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 . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] added domain '" . $domain . "'");
$result = $this->apiCall('Domains.get', array( $result = $this->apiCall('Domains.get', array(
'domainname' => $domain 'domainname' => $domain
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
@@ -842,7 +882,9 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* @param string $domainname * @param string $domainname
* optional, the domainname * optional, the domainname
* @param int $customerid * @param int $customerid
* optional customer-id * required (if $loginname is not specified)
* @param string $loginname
* required (if $customerid is not specified)
* @param int $adminid * @param int $adminid
* optional, default is the calling admin's ID * optional, default is the calling admin's ID
* @param array $ipandport * @param array $ipandport
@@ -861,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) * optional, when setting $speciallogfile to false, this needs to be set to true to confirm the action, default 0 (false)
* @param int $alias * @param int $alias
* optional, domain-id of a domain that the new domain should be an alias of, default 0 (none) * 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) * 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 * @param string $registration_date
* optional, date of domain registration in form of YYYY-MM-DD, default empty (none) * optional, date of domain registration in form of YYYY-MM-DD, default empty (none)
@@ -927,6 +969,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL * optional whether to honor the (server) cipher order for this domain. default 0 (false), requires SSL
* @param bool $sessiontickets * @param bool $sessiontickets
* optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL * optional whether to enable or disable TLS sessiontickets (RFC 5077) for this domain. default 1 (true), requires SSL
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
* *
* @access admin * @access admin
* @throws \Exception * @throws \Exception
@@ -950,9 +994,18 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
// optional parameters // optional parameters
$p_ipandports = $this->getParam('ipandport', true, array()); $p_ipandports = $this->getParam('ipandport', true, array());
$customerid = intval($this->getParam('customerid', true, $result['customerid']));
$adminid = intval($this->getParam('adminid', true, $result['adminid'])); $adminid = intval($this->getParam('adminid', true, $result['adminid']));
if ($this->getParam('customerid', true, 0) == 0 && $this->getParam('loginname', true, '') == '') {
$customerid = $result['customerid'];
$customer = $this->apiCall('Customers.get', array(
'id' => $customerid
));
} else {
$customer = $this->getCustomerData();
$customerid = $customer['customerid'];
}
$subcanemaildomain = $this->getParam('subcanemaildomain', true, $result['subcanemaildomain']); $subcanemaildomain = $this->getParam('subcanemaildomain', true, $result['subcanemaildomain']);
$isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']); $isemaildomain = $this->getBoolParam('isemaildomain', true, $result['isemaildomain']);
$email_only = $this->getBoolParam('email_only', true, $result['email_only']); $email_only = $this->getBoolParam('email_only', true, $result['email_only']);
@@ -1013,6 +1066,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$ssl_cipher_list = $result['ssl_cipher_list']; $ssl_cipher_list = $result['ssl_cipher_list'];
$tlsv13_cipher_list = $result['tlsv13_cipher_list']; $tlsv13_cipher_list = $result['tlsv13_cipher_list'];
} }
$description = $this->getParam('description', true, $result['description']);
// count subdomain usage of source-domain // count subdomain usage of source-domain
$subdomains_stmt = Database::prepare(" $subdomains_stmt = Database::prepare("
@@ -1083,13 +1137,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
if (empty($customer) || $customer['customerid'] != $customerid) { if (empty($customer) || $customer['customerid'] != $customerid) {
\Froxlor\UI\Response::standard_error('customerdoesntexist', '', true); \Froxlor\UI\Response::standard_error('customerdoesntexist', '', true);
} }
} else {
$customerid = $result['customerid'];
// get customer
$customer = $this->apiCall('Customers.get', array(
'id' => $customerid
));
} }
// handle change of admin (move domain from admin to admin) // handle change of admin (move domain from admin to admin)
@@ -1142,6 +1189,38 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$serveraliasoption = $p_serveraliasoption; $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 ($this->getUserDetail('change_serversettings') == '1') {
if (Settings::Get('system.bind_enable') == '1') { if (Settings::Get('system.bind_enable') == '1') {
@@ -1155,34 +1234,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$dkim = $result['dkim']; $dkim = $result['dkim'];
} }
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $specialsettings), 'specialsettings', '/^[^\0]*$/', '', array(), true); $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', '', '', 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(); $ssl_protocols = array();
if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) { if (! empty($p_ssl_protocols) && is_numeric($p_ssl_protocols)) {
@@ -1222,7 +1274,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$notryfiles = $result['notryfiles']; $notryfiles = $result['notryfiles'];
$writeaccesslog = $result['writeaccesslog']; $writeaccesslog = $result['writeaccesslog'];
$writeerrorlog = $result['writeerrorlog']; $writeerrorlog = $result['writeerrorlog'];
$documentroot = $result['documentroot'];
$ssl_protocols = $p_ssl_protocols; $ssl_protocols = $p_ssl_protocols;
$override_tls = $result['override_tls']; $override_tls = $result['override_tls'];
} }
@@ -1311,6 +1362,15 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$include_specialsettings = 0; $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 // We can't enable let's encrypt for wildcard-domains
if ($serveraliasoption == '0' && $letsencrypt == '1') { if ($serveraliasoption == '0' && $letsencrypt == '1') {
\Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true); \Froxlor\UI\Response::standard_error('nowildcardwithletsencrypt', '', true);
@@ -1322,7 +1382,12 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
} }
if (! preg_match('/^https?\:\/\//', $documentroot)) { if (! preg_match('/^https?\:\/\//', $documentroot)) {
$documentroot = \Froxlor\FileDir::makeCorrectDir($documentroot); if ($documentroot != $result['documentroot']) {
if (substr($documentroot, 0, 1) != "/") {
$documentroot = $customer['documentroot'] . '/' . $documentroot;
}
$documentroot = \Froxlor\FileDir::makeCorrectDir($documentroot);
}
} }
if ($email_only == '1') { if ($email_only == '1') {
@@ -1399,8 +1464,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$wwwserveralias = ($serveraliasoption == '1') ? '1' : '0'; $wwwserveralias = ($serveraliasoption == '1') ? '1' : '0';
$iswildcarddomain = ($serveraliasoption == '0') ? '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']) { 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('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
} }
if ($speciallogfile != $result['speciallogfile'] && $speciallogverified != '1') { if ($speciallogfile != $result['speciallogfile'] && $speciallogverified != '1') {
@@ -1408,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']) { 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 // check whether nameserver has been disabled, #581
if ($isbinddomain != $result['isbinddomain'] && $isbinddomain == 0) { 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') { if ($isemaildomain == '0' && $result['isemaildomain'] == '1') {
@@ -1440,6 +1505,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
Database::pexecute($del_stmt, array( Database::pexecute($del_stmt, array(
'id' => $id 'id' => $id
), true, true); ), true, true);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
} }
$updatechildren = ''; $updatechildren = '';
@@ -1575,6 +1642,7 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$update_data['sslenabled'] = $sslenabled; $update_data['sslenabled'] = $sslenabled;
$update_data['honorcipherorder'] = $honorcipherorder; $update_data['honorcipherorder'] = $honorcipherorder;
$update_data['sessiontickets'] = $sessiontickets; $update_data['sessiontickets'] = $sessiontickets;
$update_data['description'] = $description;
$update_data['id'] = $id; $update_data['id'] = $id;
$update_stmt = Database::prepare(" $update_stmt = Database::prepare("
@@ -1620,7 +1688,8 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
`tlsv13_cipher_list` = :tlsv13_cipher_list, `tlsv13_cipher_list` = :tlsv13_cipher_list,
`ssl_enabled` = :sslenabled, `ssl_enabled` = :sslenabled,
`ssl_honorcipherorder` = :honorcipherorder, `ssl_honorcipherorder` = :honorcipherorder,
`ssl_sessiontickets` = :sessiontickets `ssl_sessiontickets` = :sessiontickets,
`description` = :description
WHERE `id` = :id WHERE `id` = :id
"); ");
Database::pexecute($update_stmt, $update_data, true, true); Database::pexecute($update_stmt, $update_data, true, true);
@@ -1678,9 +1747,6 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
"); ");
Database::pexecute($_update_stmt, $_update_data, true, true); Database::pexecute($_update_stmt, $_update_data, true, true);
// insert a rebuild-task
\Froxlor\System\Cronjob::inserttask('1');
// Cleanup domain <-> ip mapping // Cleanup domain <-> ip mapping
$del_stmt = Database::prepare(" $del_stmt = Database::prepare("
DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id DELETE FROM `" . TABLE_DOMAINTOIP . "` WHERE `id_domain` = :id
@@ -1764,7 +1830,10 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$idna_convert = new \Froxlor\Idna\IdnaWrapper(); $idna_convert = new \Froxlor\Idna\IdnaWrapper();
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $idna_convert->decode($result['domain']) . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated domain '" . $idna_convert->decode($result['domain']) . "'");
return $this->response(200, "successfull", $update_data); $result = $this->apiCall('Domains.get', array(
'domainname' => $result['domain']
));
return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -1915,17 +1984,17 @@ class Domains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
\Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger()); \Froxlor\Domain\Domain::triggerLetsEncryptCSRForAliasDestinationDomain($result['aliasdomain'], $this->logger());
// remove domains DNS from powerDNS if used, #581 // 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 // 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'] . ")"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_INFO, "[API] deleted domain/subdomains (#" . $result['id'] . ")");
\Froxlor\User::updateCounters(); \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 // 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, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -30,9 +30,9 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr * @param string $emailaddr
* optional email-address to add the account for * optional email-address to add the account for
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $email_password * @param string $email_password
* password for the account * password for the account
* @param string $alternative_email * @param string $alternative_email
@@ -100,8 +100,8 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
// alternative email address to send info to // alternative email address to send info to
if (Settings::Get('panel.sendalternativemail') == 1) { if (Settings::Get('panel.sendalternativemail') == 1) {
$alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true)); $alternative_email = $idna_convert->encode(\Froxlor\Validate\Validate::validate($alternative_email, 'alternative_email', '', '', array(), true));
if (! \Froxlor\Validate\Validate::validateEmail($alternative_email)) { if (! empty($alternative_email) && ! \Froxlor\Validate\Validate::validateEmail($alternative_email)) {
\Froxlor\UI\Response::standard_error('emailiswrong', $alternative_email, true); \Froxlor\UI\Response::standard_error('alternativeemailiswrong', $alternative_email, true);
} }
} else { } else {
$alternative_email = ''; $alternative_email = '';
@@ -192,7 +192,12 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$replace_arr = array( $replace_arr = array(
'EMAIL' => $email_full, 'EMAIL' => $email_full,
'USERNAME' => $username, 'USERNAME' => $username,
'PASSWORD' => $password 'PASSWORD' => htmlentities(htmlentities($password)),
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
'NAME' => $customer['name'],
'FIRSTNAME' => $customer['firstname'],
'COMPANY' => $customer['company'],
'CUSTOMER_NO' => $customer['customernumber']
); );
// get the customers admin // get the customers admin
@@ -231,7 +236,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$this->mailer()->clearAddresses(); $this->mailer()->clearAddresses();
// customer wants to send the e-mail to an alternative email address too // customer wants to send the e-mail to an alternative email address too
if (Settings::Get('panel.sendalternativemail') == 1) { if (Settings::Get('panel.sendalternativemail') == 1 && ! empty($alternative_email)) {
// get template for mail subject // get template for mail subject
$mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']); $mail_subject = $this->getMailTemplate($customer, 'mails', 'pop_success_alternative_subject', $replace_arr, $this->lng['mails']['pop_success_alternative']['subject']);
// get template for mail body // get template for mail body
@@ -268,7 +273,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full'] 'emailaddr' => $result['email_full']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
} }
@@ -290,13 +295,15 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address to update * optional, the email-address to update
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param int $email_quota * @param int $email_quota
* optional, update quota * optional, update quota
* @param string $email_password * @param string $email_password
* optional, update password * optional, update password
* @param bool $deactivated
* optional, admin-only
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -326,6 +333,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$password = $this->getParam('email_password', true, ''); $password = $this->getParam('email_password', true, '');
$quota = $this->getParam('email_quota', true, $result['quota']); $quota = $this->getParam('email_quota', true, $result['quota']);
$deactivated = $this->getBoolParam('deactivated', true, (strtolower($result['postfix']) == 'n' ? true : false));
// get needed customer info to reduce the email-account-counter by one // get needed customer info to reduce the email-account-counter by one
$customer = $this->getCustomerData(); $customer = $this->getCustomerData();
@@ -367,6 +375,18 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$quota = 0; $quota = 0;
} }
if ($this->isAdmin()) {
if (($deactivated == true && strtolower($result['postfix']) == 'y') || ($deactivated == false && strtolower($result['postfix']) == 'n')) {
if (! empty($upd_query)) {
$upd_query .= ", ";
}
$upd_query .= "`postfix` = :postfix, `imap` = :imap, `pop3` = :pop3";
$upd_params['postfix'] = $deactivated ? 'N' : 'Y';
$upd_params['imap'] = $deactivated ? '0' : '1';
$upd_params['pop3'] = $deactivated ? '0' : '1';
}
}
// build update query // build update query
if (! empty($upd_query)) { if (! empty($upd_query)) {
$upd_stmt = Database::prepare(" $upd_stmt = Database::prepare("
@@ -384,7 +404,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full'] 'emailaddr' => $result['email_full']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -413,9 +433,9 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address to delete the account for * optional, the email-address to delete the account for
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param bool $delete_userfiles * @param bool $delete_userfiles
* optional, default false * optional, default false
* *
@@ -479,7 +499,7 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
} }
if ($delete_userfiles) { 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 // decrease usage for customer
@@ -487,6 +507,6 @@ class EmailAccounts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Reso
Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $quota); Customers::decreaseUsage($customer['customerid'], 'email_quota_used', '', $quota);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email account for '" . $result['email_full'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email account for '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }

View File

@@ -30,9 +30,9 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address to add the forwarder for * optional, the email-address to add the forwarder for
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $destination * @param string $destination
* email-address to add as forwarder * email-address to add as forwarder
* *
@@ -102,7 +102,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full'] 'emailaddr' => $result['email_full']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
} }
@@ -168,7 +168,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
]; ];
} }
return $this->response(200, "successfull", [ return $this->response(200, "successful", [
'count' => count($destination), 'count' => count($destination),
'list' => $destination 'list' => $destination
]); ]);
@@ -210,7 +210,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result['destination'] = explode(' ', $result['destination']); $result['destination'] = explode(' ', $result['destination']);
return $this->response(200, "successfull", count($result['destination'])); return $this->response(200, "successful", count($result['destination']));
} }
/** /**
@@ -221,9 +221,9 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address to delete the forwarder from * optional, the email-address to delete the forwarder from
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param int $forwarderid * @param int $forwarderid
* id of the forwarder to delete * id of the forwarder to delete
* *
@@ -280,7 +280,7 @@ class EmailForwarders extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Re
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full'] 'emailaddr' => $result['email_full']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Unknown forwarder id", 404); throw new \Exception("Unknown forwarder id", 404);
} }

View File

@@ -32,9 +32,11 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param boolean $iscatchall * @param boolean $iscatchall
* optional, make this address a catchall address, default: no * optional, make this address a catchall address, default: no
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -54,6 +56,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters // parameters
$iscatchall = $this->getBoolParam('iscatchall', true, 0); $iscatchall = $this->getBoolParam('iscatchall', true, 0);
$description = $this->getParam('description', true, '');
$disablegreylist = $this->getBoolParam('disablegreylist', true, 0); $disablegreylist = $this->getBoolParam('disablegreylist', true, 0);
// validation // validation
@@ -63,9 +66,10 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
} }
// check domain and whether it's an email-enabled domain // check domain and whether it's an email-enabled domain
// use internal call because the customer might have 'domains' in customer_hide_options
$domain_check = $this->apiCall('SubDomains.get', array( $domain_check = $this->apiCall('SubDomains.get', array(
'domainname' => $domain 'domainname' => $domain
)); ), true);
if ($domain_check['isemaildomain'] == 0) { if ($domain_check['isemaildomain'] == 0) {
\Froxlor\UI\Response::standard_error('maindomainnonexist', $domain, true); \Froxlor\UI\Response::standard_error('maindomainnonexist', $domain, true);
} }
@@ -125,7 +129,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`email_full` = :email_full, `email_full` = :email_full,
`iscatchall` = :iscatchall, `iscatchall` = :iscatchall,
`disablegreylist` = :disablegreylist, `disablegreylist` = :disablegreylist,
`domainid` = :domainid `domainid` = :domainid,
`description` = :description
"); ");
$params = array( $params = array(
"cid" => $customer['customerid'], "cid" => $customer['customerid'],
@@ -133,7 +138,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
"email_full" => $email_full, "email_full" => $email_full,
"iscatchall" => $iscatchall, "iscatchall" => $iscatchall,
"disablegreylist" => $disablegreylist, "disablegreylist" => $disablegreylist,
"domainid" => $domain_check['id'] "domainid" => $domain_check['id'],
"description" => $description
); );
Database::pexecute($stmt, $params, true, true); Database::pexecute($stmt, $params, true, true);
@@ -145,7 +151,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $email_full 'emailaddr' => $email_full
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
} }
@@ -172,7 +178,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$customer_ids = $this->getAllowedCustomerIds('email'); $customer_ids = $this->getAllowedCustomerIds('email');
$params['idea'] = ($id <= 0 ? $emailaddr : $id); $params['idea'] = ($id <= 0 ? $emailaddr : $id);
$result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, u.`quota`, v.`disablegreylist` $result_stmt = Database::prepare("SELECT v.`id`, v.`email`, v.`email_full`, v.`iscatchall`, v.`destination`, v.`customerid`, v.`popaccountid`, v.`domainid`, v.`description`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`, v.`disablegreylist`
FROM `" . TABLE_MAIL_VIRTUAL . "` v FROM `" . TABLE_MAIL_VIRTUAL . "` v
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id` LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON v.`popaccountid` = u.`id`
WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ") WHERE v.`customerid` IN (" . implode(", ", $customer_ids) . ")
@@ -181,7 +187,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get email address '" . $result['email_full'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get email address '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "emailaddr '" . $emailaddr . "'"); $key = ($id > 0 ? "id #" . $id : "emailaddr '" . $emailaddr . "'");
throw new \Exception("Email address with " . $key . " could not be found", 404); throw new \Exception("Email address with " . $key . " could not be found", 404);
@@ -195,11 +201,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address * optional, the email-address
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param boolean $iscatchall * @param boolean $iscatchall
* optional * optional
* @param string $description
* optional custom description (currently not used/shown in the frontend), default empty
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -232,6 +240,8 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
// parameters // parameters
$iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']); $iscatchall = $this->getBoolParam('iscatchall', true, $result['iscatchall']);
$description = $this->getParam('description', true, $result['description']);
// get needed customer info to reduce the email-address-counter by one // get needed customer info to reduce the email-address-counter by one
$customer = $this->getCustomerData(); $customer = $this->getCustomerData();
@@ -260,12 +270,13 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$stmt = Database::prepare(" $stmt = Database::prepare("
UPDATE `" . TABLE_MAIL_VIRTUAL . "` UPDATE `" . TABLE_MAIL_VIRTUAL . "`
SET `email` = :email , `iscatchall` = :caflag SET `email` = :email , `iscatchall` = :caflag, `description` = :description
WHERE `customerid`= :cid AND `id`= :id WHERE `customerid`= :cid AND `id`= :id
"); ");
$params = array( $params = array(
"email" => $email, "email" => $email,
"caflag" => $iscatchall, "caflag" => $iscatchall,
"description" => $description,
"cid" => $customer['customerid'], "cid" => $customer['customerid'],
"id" => $id "id" => $id
); );
@@ -275,7 +286,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Emails.get', array( $result = $this->apiCall('Emails.get', array(
'emailaddr' => $result['email_full'] 'emailaddr' => $result['email_full']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
* toggle greylist flag of given email address either by id or email-address * toggle greylist flag of given email address either by id or email-address
@@ -394,7 +405,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = array(); $result = array();
$query_fields = array(); $query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, u.`quota`, m.`destination`, m.`popaccountid`, d.`domain`, u.`mboxsize` SELECT m.`id`, m.`domainid`, m.`email`, m.`email_full`, m.`iscatchall`, m.`destination`, m.`popaccountid`, d.`domain`, u.`quota`, u.`imap`, u.`pop3`, u.`postfix`, u.`mboxsize`
FROM `" . TABLE_MAIL_VIRTUAL . "` m FROM `" . TABLE_MAIL_VIRTUAL . "` m
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`) LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` d ON (m.`domainid` = d.`id`)
LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`) LEFT JOIN `" . TABLE_MAIL_USERS . "` u ON (m.`popaccountid` = u.`id`)
@@ -404,14 +415,14 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list email-addresses"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list email-addresses");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable email addresses * returns the total number of accessible email addresses
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select email addresses of a specific customer by id * optional, admin-only, select email addresses of a specific customer by id
@@ -434,7 +445,7 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_emails']); return $this->response(200, "successful", $result['num_emails']);
} }
} }
@@ -446,9 +457,9 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $emailaddr * @param string $emailaddr
* optional, the email-address * optional, the email-address
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* @param boolean $delete_userfiles * @param boolean $delete_userfiles
* optional, delete email data from filesystem, default: 0 (false) * optional, delete email data from filesystem, default: 0 (false)
* *
@@ -499,10 +510,6 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders); Customers::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
Admins::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders); Admins::decreaseUsage($customer['customerid'], 'email_forwarders_used', '', $number_forwarders);
if ($delete_userfiles) {
\Froxlor\System\Cronjob::inserttask('7', $customer['loginname'], $result['email_full']);
}
// delete address // delete address
$stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `id`= :id"); $stmt = Database::prepare("DELETE FROM `" . TABLE_MAIL_VIRTUAL . "` WHERE `customerid`= :customerid AND `id`= :id");
Database::pexecute($stmt, array( Database::pexecute($stmt, array(
@@ -512,6 +519,6 @@ class Emails extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'emails_used'); Customers::decreaseUsage($customer['customerid'], 'emails_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email address '" . $result['email_full'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] deleted email address '" . $result['email_full'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }

View File

@@ -70,7 +70,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$fpmdaemons[] = $row; $fpmdaemons[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($fpmdaemons), 'count' => count($fpmdaemons),
'list' => $fpmdaemons 'list' => $fpmdaemons
)); ));
@@ -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 * @access admin
* @throws \Exception * @throws \Exception
@@ -93,7 +93,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_fpms']); return $this->response(200, "successful", $result['num_fpms']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -121,7 +121,7 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'id' => $id 'id' => $id
), true, true); ), true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("fpm-daemon with id #" . $id . " could not be found", 404); throw new \Exception("fpm-daemon with id #" . $id . " could not be found", 404);
} }
@@ -178,9 +178,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$custom_config = $this->getParam('custom_config', true, ''); $custom_config = $this->getParam('custom_config', true, '');
// validation // 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); $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( if (! in_array($pmanager, array(
'static', 'static',
'dynamic', 'dynamic',
@@ -229,12 +229,12 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Database::pexecute($ins_stmt, $ins_data); Database::pexecute($ins_stmt, $ins_data);
$id = Database::lastInsertId(); $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') . "'"); $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( $result = $this->apiCall('FpmDaemons.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -299,9 +299,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$custom_config = $this->getParam('custom_config', true, $result['custom_config']); $custom_config = $this->getParam('custom_config', true, $result['custom_config']);
// validation // 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); $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( if (! in_array($pmanager, array(
'static', 'static',
'dynamic', 'dynamic',
@@ -351,12 +351,12 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
); );
Database::pexecute($upd_stmt, $upd_data, true, true); 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') . "'"); $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( $result = $this->apiCall('FpmDaemons.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -400,9 +400,9 @@ class FpmDaemons extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'id' => $id 'id' => $id
), true, true); ), 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') . "'"); $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, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -74,7 +74,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
// zum update schritt #1 -> download // zum update schritt #1 -> download
if ($isnewerversion == 1) { if ($isnewerversion == 1) {
$text = 'There is a newer version available: "' . $_version . '" (Your current version is: ' . $this->version . ')'; $text = 'There is a newer version available: "' . $_version . '" (Your current version is: ' . $this->version . ')';
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'isnewerversion' => $isnewerversion, 'isnewerversion' => $isnewerversion,
'version' => $_version, 'version' => $_version,
'message' => $text, 'message' => $text,
@@ -83,7 +83,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
)); ));
} elseif ($isnewerversion == 0) { } elseif ($isnewerversion == 0) {
// all good // all good
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'isnewerversion' => $isnewerversion, 'isnewerversion' => $isnewerversion,
'version' => $version_label, 'version' => $version_label,
'message' => "", 'message' => "",
@@ -95,7 +95,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
} }
} }
} }
return $this->response(300, "successfull", array( return $this->response(300, "successful", array(
'isnewerversion' => 0, 'isnewerversion' => 0,
'version' => $this->version . $this->branding, 'version' => $this->version . $this->branding,
'message' => 'Version-check not available due to missing php-curl extension', 'message' => 'Version-check not available due to missing php-curl extension',
@@ -123,13 +123,13 @@ class Froxlor extends \Froxlor\Api\ApiCommand
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " imported settings"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " imported settings");
try { try {
\Froxlor\SImExporter::import($json_str); \Froxlor\SImExporter::import($json_str);
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
\Froxlor\System\Cronjob::inserttask('10'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_QUOTA);
// Using nameserver, insert a task which rebuilds the server config // 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 // cron.d file
\Froxlor\System\Cronjob::inserttask('99'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_CRON);
return $this->response(200, "successfull", true); return $this->response(200, "successful", true);
} catch (\Exception $e) { } catch (\Exception $e) {
throw new \Exception($e->getMessage(), 406); throw new \Exception($e->getMessage(), 406);
} }
@@ -149,7 +149,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) { if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " exported settings"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "User " . $this->getUserDetail('loginname') . " exported settings");
$json_export = \Froxlor\SImExporter::export(); $json_export = \Froxlor\SImExporter::export();
return $this->response(200, "successfull", $json_export); return $this->response(200, "successful", $json_export);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -175,7 +175,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
'value' => $row['value'] 'value' => $row['value']
); );
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -197,7 +197,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
{ {
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) { if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$setting = $this->getParam('key'); $setting = $this->getParam('key');
return $this->response(200, "successfull", Settings::Get($setting)); return $this->response(200, "successful", Settings::Get($setting));
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -227,7 +227,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
throw new \Exception("Setting '" . $setting . "' could not be found"); throw new \Exception("Setting '" . $setting . "' could not be found");
} }
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] Changing setting '" . $setting . "' from '" . $oldvalue . "' to '" . $value . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] Changing setting '" . $setting . "' from '" . $oldvalue . "' to '" . $value . "'");
return $this->response(200, "successfull", Settings::Set($setting, $value, true)); return $this->response(200, "successful", Settings::Set($setting, $value, true));
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -240,7 +240,27 @@ class Froxlor extends \Froxlor\Api\ApiCommand
*/ */
public function generatePassword() public function generatePassword()
{ {
return $this->response(200, "successfull", \Froxlor\System\Crypt::generatePassword()); return $this->response(200, "successful", \Froxlor\System\Crypt::generatePassword());
}
/**
* can be used to remotely run the integritiy checks froxlor implements
*
* @access admin
* @throws \Exception
* @return string
*/
public function integrityCheck()
{
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$integrity = new \Froxlor\Database\IntegrityCheck();
$result = $integrity->checkAll();
if ($result) {
return $this->response(200, "successful", "OK");
}
throw new \Exception("Some checks failed.", 406);
}
throw new \Exception("Not allowed to execute given command.", 403);
} }
/** /**
@@ -313,7 +333,7 @@ class Froxlor extends \Froxlor\Api\ApiCommand
} }
// return the list // return the list
return $this->response(200, "successfull", $functions); return $this->response(200, "successful", $functions);
} }
/** /**

View File

@@ -40,7 +40,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* @param string $ftp_domain * @param string $ftp_domain
* optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner) * optional if customer.ftpatdomain is allowed, specify a domain (customer must be owner)
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* @param array $additional_members * @param array $additional_members
* optional whether to add additional usernames to the group * optional whether to add additional usernames to the group
* @param bool $is_defaultuser * @param bool $is_defaultuser
@@ -60,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) { 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'); $path = $this->getParam('path');
$password = $this->getParam('ftp_password'); $password = $this->getParam('ftp_password');
@@ -77,7 +79,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
$password = \Froxlor\System\Crypt::validatePassword($password, 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') { if (Settings::Get('system.allow_customer_shell') == '1') {
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true); $shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
@@ -180,6 +182,17 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
), true, true); ), true, true);
} }
// create quotatallies entry if it not exists, refs #885
if ($result_stmt->rowCount() == 0) {
$stmt = Database::prepare("INSERT INTO `" . TABLE_FTP_QUOTATALLIES . "`
(`name`, `quota_type`, `bytes_in_used`, `bytes_out_used`, `bytes_xfer_used`, `files_in_used`, `files_out_used`, `files_xfer_used`)
VALUES (:name, 'user', '0', '0', '0', '0', '0', '0')
");
Database::pexecute($stmt, array(
"name" => $username
), true, true);
}
$group_upd_stmt = Database::prepare(" $group_upd_stmt = Database::prepare("
UPDATE `" . TABLE_FTP_GROUPS . "` UPDATE `" . TABLE_FTP_GROUPS . "`
SET `members` = CONCAT_WS(',',`members`, :username) SET `members` = CONCAT_WS(',',`members`, :username)
@@ -221,14 +234,18 @@ 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 . ")'"); $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) { if ($sendinfomail == 1) {
$replace_arr = array( $replace_arr = array(
'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer), 'SALUTATION' => \Froxlor\User::getCorrectUserSalutation($customer),
'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($customer), // < keep this for compatibility 'CUST_NAME' => \Froxlor\User::getCorrectUserSalutation($customer), // < keep this for compatibility
'NAME' => $customer['name'],
'FIRSTNAME' => $customer['firstname'],
'COMPANY' => $customer['company'],
'CUSTOMER_NO' => $customer['customernumber'],
'USR_NAME' => $username, 'USR_NAME' => $username,
'USR_PASS' => $password, 'USR_PASS' => htmlentities(htmlentities($password)),
'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path)) 'USR_PATH' => \Froxlor\FileDir::makeCorrectDir(str_replace($customer['documentroot'], "/", $path))
); );
// get template for mail subject // get template for mail subject
@@ -264,7 +281,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = $this->apiCall('Ftps.get', array( $result = $this->apiCall('Ftps.get', array(
'username' => $username 'username' => $username
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
@@ -325,7 +342,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get ftp-user '" . $result['username'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "username '" . $username . "'"); $key = ($id > 0 ? "id #" . $id : "username '" . $username . "'");
throw new \Exception("FTP user with " . $key . " could not be found", 404); throw new \Exception("FTP user with " . $key . " could not be found", 404);
@@ -335,11 +352,11 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* update a given ftp-user by id or username * update a given ftp-user by id or username
* *
* @param int $id * @param int $id
* optional, the customer-id * optional, the ftp-user-id
* @param string $username * @param string $username
* optional, the username * optional, the username
* @param string $ftp_password * @param string $ftp_password
* password for the created database and database-user * optional, update password if specified
* @param string $path * @param string $path
* destination path relative to the customers-homedir * destination path relative to the customers-homedir
* @param string $ftp_description * @param string $ftp_description
@@ -347,7 +364,9 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
* @param string $shell * @param string $shell
* optional, default /bin/false (not changeable when deactivated) * optional, default /bin/false (not changeable when deactivated)
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -377,7 +396,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $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') { if (Settings::Get('system.allow_customer_shell') == '1') {
$shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true); $shell = \Froxlor\Validate\Validate::validate(trim($shell), 'shell', '', '', array(), true);
@@ -431,7 +450,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
} }
// it's the task for "new ftp" but that will // it's the task for "new ftp" but that will
// create all directories and correct their permissions // create all directories and correct their permissions
\Froxlor\System\Cronjob::inserttask(5); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::CREATE_FTP);
$stmt = Database::prepare(" $stmt = Database::prepare("
UPDATE `" . TABLE_FTP_USERS . "` UPDATE `" . TABLE_FTP_USERS . "`
@@ -450,7 +469,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
'username' => $result['username'] 'username' => $result['username']
)); ));
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] updated ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -486,14 +505,14 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list ftp-users"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list ftp-users");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable ftp accounts * returns the total number of accessible ftp accounts
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select ftp-users of a specific customer by id * optional, admin-only, select ftp-users of a specific customer by id
@@ -514,7 +533,7 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_ftps']); return $this->response(200, "successful", $result['num_ftps']);
} }
} }
@@ -609,11 +628,11 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
// refs #293 // refs #293
if ($delete_userfiles == 1) { 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 { } else {
if (Settings::Get('system.nssextrausers') == 1) { if (Settings::Get('system.nssextrausers') == 1) {
// this is used so that the libnss-extrausers cron is fired // 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);
} }
} }
@@ -622,6 +641,6 @@ class Ftps extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEntit
Customers::decreaseUsage($customer_data['customerid'], 'ftps_used', $resetaccnumber); Customers::decreaseUsage($customer_data['customerid'], 'ftps_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted ftp-user '" . $result['username'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted ftp-user '" . $result['username'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }

View File

@@ -57,7 +57,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -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 * @access admin
* @throws \Exception * @throws \Exception
@@ -85,7 +85,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
} }
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_plans']); return $this->response(200, "successful", $result['num_plans']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -120,7 +120,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get hosting-plan '" . $result['name'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "planname '" . $planname . "'"); $key = ($id > 0 ? "id #" . $id : "planname '" . $planname . "'");
throw new \Exception("Hosting-plan with " . $key . " could not be found", 404); throw new \Exception("Hosting-plan with " . $key . " could not be found", 404);
@@ -182,9 +182,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* @param bool $perlenabled * @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false) * optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled * @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 * @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 * @access admin
* @throws \Exception * @throws \Exception
@@ -216,7 +216,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
// validation // validation
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true); $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') { if (Settings::Get('system.mail_quota_enabled') != '1') {
$value_arr['email_quota'] = - 1; $value_arr['email_quota'] = - 1;
@@ -246,7 +246,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
$result = $this->apiCall('HostingPlans.get', array( $result = $this->apiCall('HostingPlans.get', array(
'planname' => $name 'planname' => $name
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -309,9 +309,9 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
* @param bool $perlenabled * @param bool $perlenabled
* optional, whether to allow usage of Perl/CGI, default 0 (false) * optional, whether to allow usage of Perl/CGI, default 0 (false)
* @param bool $dnsenabled * @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 * @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 * @access admin
* @throws \Exception * @throws \Exception
@@ -361,7 +361,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
// validation // validation
$name = \Froxlor\Validate\Validate::validate(trim($name), 'name', '', '', array(), true); $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') { if (Settings::Get('system.mail_quota_enabled') != '1') {
$value_arr['email_quota'] = - 1; $value_arr['email_quota'] = - 1;
@@ -393,7 +393,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
); );
Database::pexecute($upd_stmt, $update_data, true, true); Database::pexecute($upd_stmt, $update_data, true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated hosting-plan '" . $result['name'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] updated hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $update_data); return $this->response(200, "successful", $update_data);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -431,7 +431,7 @@ class HostingPlans extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resou
'id' => $id 'id' => $id
), true, true); ), true, true);
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted hosting-plan '" . $result['name'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted hosting-plan '" . $result['name'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -51,12 +51,12 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$query_fields = array(); $query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . $this->getSearchWhere($query_fields, $append_where) . $this->getOrderBy() . $this->getLimit()); SELECT * FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where . $this->getSearchWhere($query_fields, $append_where) . $this->getOrderBy() . $this->getLimit());
Database::pexecute($result_stmt, null, true, true); Database::pexecute($result_stmt, $query_fields, true, true);
$result = array(); $result = array();
while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $result_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -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 * @access admin
* @throws \Exception * @throws \Exception
@@ -82,7 +82,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
SELECT COUNT(*) as num_ips FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where); SELECT COUNT(*) as num_ips FROM `" . TABLE_PANEL_IPSANDPORTS . "` " . $ip_where);
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_ips']); return $this->response(200, "successful", $result['num_ips']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -116,7 +116,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
), true, true); ), true, true);
if ($result) { if ($result) {
$this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get ip " . $result['ip'] . " " . $result['port']); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_NOTICE, "[API] get ip " . $result['ip'] . " " . $result['port']);
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("IP/port with id #" . $id . " could not be found", 404); throw new \Exception("IP/port with id #" . $id . " could not be found", 404);
} }
@@ -170,18 +170,18 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
{ {
if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) { if ($this->isAdmin() && $this->getUserDetail('change_serversettings')) {
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, false, false, false, true); $ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip'), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array( $port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, 80), 'port', \Froxlor\Validate\Validate::REGEX_PORT, array(
'stringisempty', 'stringisempty',
'myport' 'myport'
), array(), true); ), array(), true);
$listen_statement = ! empty($this->getBoolParam('listen_statement', true, 0)) ? 1 : 0; $listen_statement = ! empty($this->getBoolParam('listen_statement', true, 0)) ? 1 : 0;
$namevirtualhost_statement = ! empty($this->getBoolParam('namevirtualhost_statement', true, 0)) ? 1 : 0; $namevirtualhost_statement = ! empty($this->getBoolParam('namevirtualhost_statement', true, 0)) ? 1 : 0;
$vhostcontainer = ! empty($this->getBoolParam('vhostcontainer', true, 0)) ? 1 : 0; $vhostcontainer = ! empty($this->getBoolParam('vhostcontainer', true, 0)) ? 1 : 0;
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, '')), 'specialsettings', '/^[^\0]*$/', '', array(), true); $specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, '')), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$vhostcontainer_servername_statement = ! empty($this->getBoolParam('vhostcontainer_servername_statement', true, 1)) ? 1 : 0; $vhostcontainer_servername_statement = ! empty($this->getBoolParam('vhostcontainer_servername_statement', true, 1)) ? 1 : 0;
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, '')), 'default_vhostconf_domain', '/^[^\0]*$/', '', array(), true); $default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, '')), 'default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, ''), 'docroot', '', '', array(), true); $docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, ''), 'docroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
if ((int) Settings::Get('system.use_ssl') == 1) { if ((int) Settings::Get('system.use_ssl') == 1) {
$ssl = ! empty($this->getBoolParam('ssl', true, 0)) ? intval($this->getBoolParam('ssl', true, 0)) : 0; $ssl = ! empty($this->getBoolParam('ssl', true, 0)) ? intval($this->getBoolParam('ssl', true, 0)) : 0;
@@ -189,9 +189,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true); $ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, ''), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true); $ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, ''), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true); $ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, ''), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true); $ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, '')), 'ssl_specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_specialsettings = ! empty($this->getBoolParam('include_specialsettings', true, 0)) ? 1 : 0; $include_specialsettings = ! empty($this->getBoolParam('include_specialsettings', true, 0)) ? 1 : 0;
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true); $ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, '')), 'ssl_default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_default_vhostconf_domain = ! empty($this->getBoolParam('include_default_vhostconf_domain', true, 0)) ? 1 : 0; $include_default_vhostconf_domain = ! empty($this->getBoolParam('include_default_vhostconf_domain', true, 0)) ? 1 : 0;
} else { } else {
$ssl = 0; $ssl = 0;
@@ -247,6 +247,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$docroot = ''; $docroot = '';
} }
// always use compressed ipv6 format
$ip = inet_ntop(inet_pton($ip));
$result_checkfordouble_stmt = Database::prepare(" $result_checkfordouble_stmt = Database::prepare("
SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "` SELECT `id` FROM `" . TABLE_PANEL_IPSANDPORTS . "`
WHERE `ip` = :ip AND `port` = :port"); 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); Database::pexecute($ins_stmt, $ins_data);
$ins_data['id'] = Database::lastInsertId(); $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 // 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)) { if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$ip = '[' . $ip . ']'; $ip = '[' . $ip . ']';
@@ -307,7 +310,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$result = $this->apiCall('IpsAndPorts.get', array( $result = $this->apiCall('IpsAndPorts.get', array(
'id' => $ins_data['id'] 'id' => $ins_data['id']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }
@@ -367,18 +370,18 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id 'id' => $id
)); ));
$ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, false, false, false, true); $ip = \Froxlor\Validate\Validate::validate_ip2($this->getParam('ip', true, $result['ip']), false, 'invalidip', false, true, false, false, true);
$port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', '/^(([1-9])|([1-9][0-9])|([1-9][0-9][0-9])|([1-9][0-9][0-9][0-9])|([1-5][0-9][0-9][0-9][0-9])|(6[0-4][0-9][0-9][0-9])|(65[0-4][0-9][0-9])|(655[0-2][0-9])|(6553[0-5]))$/Di', array( $port = \Froxlor\Validate\Validate::validate($this->getParam('port', true, $result['port']), 'port', \Froxlor\Validate\Validate::REGEX_PORT, array(
'stringisempty', 'stringisempty',
'myport' 'myport'
), array(), true); ), array(), true);
$listen_statement = $this->getBoolParam('listen_statement', true, $result['listen_statement']); $listen_statement = $this->getBoolParam('listen_statement', true, $result['listen_statement']);
$namevirtualhost_statement = $this->getBoolParam('namevirtualhost_statement', true, $result['namevirtualhost_statement']); $namevirtualhost_statement = $this->getBoolParam('namevirtualhost_statement', true, $result['namevirtualhost_statement']);
$vhostcontainer = $this->getBoolParam('vhostcontainer', true, $result['vhostcontainer']); $vhostcontainer = $this->getBoolParam('vhostcontainer', true, $result['vhostcontainer']);
$specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, $result['specialsettings'])), 'specialsettings', '/^[^\0]*$/', '', array(), true); $specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('specialsettings', true, $result['specialsettings'])), 'specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$vhostcontainer_servername_statement = $this->getParam('vhostcontainer_servername_statement', true, $result['vhostcontainer_servername_statement']); $vhostcontainer_servername_statement = $this->getParam('vhostcontainer_servername_statement', true, $result['vhostcontainer_servername_statement']);
$default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, $result['default_vhostconf_domain'])), 'default_vhostconf_domain', '/^[^\0]*$/', '', array(), true); $default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('default_vhostconf_domain', true, $result['default_vhostconf_domain'])), 'default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, $result['docroot']), 'docroot', '', '', array(), true); $docroot = \Froxlor\Validate\Validate::validate($this->getParam('docroot', true, $result['docroot']), 'docroot', \Froxlor\Validate\Validate::REGEX_DIR, '', array(), true);
if ((int) Settings::Get('system.use_ssl') == 1) { if ((int) Settings::Get('system.use_ssl') == 1) {
$ssl = $this->getBoolParam('ssl', true, $result['ssl']); $ssl = $this->getBoolParam('ssl', true, $result['ssl']);
@@ -386,9 +389,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true); $ssl_key_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_key_file', $ssl, $result['ssl_key_file']), 'ssl_key_file', '', '', array(), true);
$ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true); $ssl_ca_file = \Froxlor\Validate\Validate::validate($this->getParam('ssl_ca_file', true, $result['ssl_ca_file']), 'ssl_ca_file', '', '', array(), true);
$ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true); $ssl_cert_chainfile = \Froxlor\Validate\Validate::validate($this->getParam('ssl_cert_chainfile', true, $result['ssl_cert_chainfile']), 'ssl_cert_chainfile', '', '', array(), true);
$ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings'])), 'ssl_specialsettings', '/^[^\0]*$/', '', array(), true); $ssl_specialsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_specialsettings', true, $result['ssl_specialsettings'])), 'ssl_specialsettings', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']); $include_specialsettings = $this->getBoolParam('include_specialsettings', true, $result['include_specialsettings']);
$ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, $result['ssl_default_vhostconf_domain'])), 'ssl_default_vhostconf_domain', '/^[^\0]*$/', '', array(), true); $ssl_default_vhostconf_domain = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $this->getParam('ssl_default_vhostconf_domain', true, $result['ssl_default_vhostconf_domain'])), 'ssl_default_vhostconf_domain', \Froxlor\Validate\Validate::REGEX_CONF_TEXT, '', array(), true);
$include_default_vhostconf_domain = $this->getBoolParam('include_default_vhostconf_domain', true, $result['include_default_vhostconf_domain']); $include_default_vhostconf_domain = $this->getBoolParam('include_default_vhostconf_domain', true, $result['include_default_vhostconf_domain']);
} else { } else {
$ssl = 0; $ssl = 0;
@@ -462,6 +465,9 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$docroot = ''; $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) { if ($result['ip'] != $ip && $result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport == false) {
\Froxlor\UI\Response::standard_error('cantchangesystemip', '', true); \Froxlor\UI\Response::standard_error('cantchangesystemip', '', true);
} elseif ($result_checkfordouble && $result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) { } elseif ($result_checkfordouble && $result_checkfordouble['id'] != '' && $result_checkfordouble['id'] != $id) {
@@ -505,16 +511,16 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
); );
Database::pexecute($upd_stmt, $upd_data); 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 // 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 . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] changed IP/port from '" . $result['ip'] . ":" . $result['port'] . "' to '" . $ip . ":" . $port . "'");
$result = $this->apiCall('IpsAndPorts.get', array( $result = $this->apiCall('IpsAndPorts.get', array(
'id' => $result['id'] 'id' => $result['id']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -560,7 +566,7 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'ip' => $result['ip'] 'ip' => $result['ip']
)); ));
if (($result['ip'] != Settings::Get('system.ipaddress')) || ($result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport == false)) { if (($result['ip'] != Settings::Get('system.ipaddress')) || ($result['ip'] == Settings::Get('system.ipaddress') && $result_sameipotherport != false)) {
$del_stmt = Database::prepare(" $del_stmt = Database::prepare("
DELETE FROM `" . TABLE_PANEL_IPSANDPORTS . "` DELETE FROM `" . TABLE_PANEL_IPSANDPORTS . "`
@@ -578,12 +584,12 @@ class IpsAndPorts extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id 'id' => $id
), true, true); ), 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 // 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'] . "'"); $this->logger()->logAction(\Froxlor\FroxlorLogger::ADM_ACTION, LOG_WARNING, "[API] deleted IP/port '" . $result['ip'] . ":" . $result['port'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} else { } else {
\Froxlor\UI\Response::standard_error('cantdeletesystemip', '', true); \Froxlor\UI\Response::standard_error('cantdeletesystemip', '', true);
} }

View File

@@ -1,4 +1,5 @@
<?php <?php
namespace Froxlor\Api\Commands; namespace Froxlor\Api\Commands;
use Froxlor\Database\Database; use Froxlor\Database\Database;
@@ -31,12 +32,14 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* optional, default is 0 * optional, default is 0
* @param string $description * @param string $description
* optional, description for database * optional, description for database
* @param string $custom_suffix
* optional, name for database
* @param bool $sendinfomail * @param bool $sendinfomail
* optional, send created resource-information to customer, default: false * optional, send created resource-information to customer, default: false
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -44,50 +47,60 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
*/ */
public function add() public function add()
{ {
// required paramters if (($this->getUserDetail('mysqls_used') < $this->getUserDetail('mysqls') || $this->getUserDetail('mysqls') == '-1') || $this->isAdmin()) {
$password = $this->getParam('mysql_password'); // required parameters
$password = $this->getParam('mysql_password');
// parameters // parameters
$dbserver = $this->getParam('mysql_server', true, 0); $dbserver = $this->getParam('mysql_server', true, 0);
$databasedescription = $this->getParam('description', true, ''); $databasedescription = $this->getParam('description', true, '');
$sendinfomail = $this->getBoolParam('sendinfomail', true, 0); $databasename = $this->getParam('custom_suffix', true, '');
// get needed customer info to reduce the mysql-usage-counter by one $sendinfomail = $this->getBoolParam('sendinfomail', true, 0);
$customer = $this->getCustomerData('mysqls'); // get needed customer info to reduce the mysql-usage-counter by one
$customer = $this->getCustomerData('mysqls');
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true);
$password = \Froxlor\System\Crypt::validatePassword($password, true); $password = \Froxlor\System\Crypt::validatePassword($password, 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 (!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 // validate whether the dbserver exists
$dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true); $dbserver = \Froxlor\Validate\Validate::validate($dbserver, html_entity_decode($this->lng['mysql']['mysql_server']), '', '', 0, true);
Database::needRoot(true, $dbserver); Database::needRoot(true, $dbserver);
Database::needSqlData(); Database::needSqlData();
$sql_root = Database::getSqlData(); $sql_root = Database::getSqlData();
Database::needRoot(false); Database::needRoot(false);
if (! isset($sql_root) || ! is_array($sql_root)) { if (!isset($sql_root) || !is_array($sql_root)) {
throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404); throw new \Exception("Database server with index #" . $dbserver . " is unknown", 404);
} }
if ($sendinfomail != 1) { if ($sendinfomail != 1) {
$sendinfomail = 0; $sendinfomail = 0;
} }
$newdb_params = array( $newdb_params = array(
'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')), 'loginname' => ($this->isAdmin() ? $customer['loginname'] : $this->getUserDetail('loginname')),
'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber')) 'mysql_lastaccountnumber' => ($this->isAdmin() ? $customer['mysql_lastaccountnumber'] : $this->getUserDetail('mysql_lastaccountnumber'))
); );
// create database, user, set permissions, etc.pp. // create database, user, set permissions, etc.pp.
$dbm = new \Froxlor\Database\DbManager($this->logger()); $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 (strtoupper(Settings::Get('customer.mysqlprefix')) == 'DBNAME' && !empty($databasename)) {
if ($username == false) { $username = $dbm->createDatabase($newdb_params['loginname'] . '_' . $databasename, $password);
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true); } else {
} $username = $dbm->createDatabase($newdb_params['loginname'], $password, $newdb_params['mysql_lastaccountnumber']);
}
// add database info to froxlor // we've checked against the password in dbm->createDatabase
$stmt = Database::prepare(" if ($username == false) {
\Froxlor\UI\Response::standard_error('passwordshouldnotbeusername', '', true);
}
// add database info to froxlor
$stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DATABASES . "` INSERT INTO `" . TABLE_PANEL_DATABASES . "`
SET SET
`customerid` = :customerid, `customerid` = :customerid,
@@ -95,77 +108,83 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
`description` = :description, `description` = :description,
`dbserver` = :dbserver `dbserver` = :dbserver
"); ");
$params = array( $params = array(
"customerid" => $customer['customerid'], "customerid" => $customer['customerid'],
"databasename" => $username, "databasename" => $username,
"description" => $databasedescription, "description" => $databasedescription,
"dbserver" => $dbserver "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
'DB_NAME' => $username,
'DB_PASS' => $password,
'DB_DESC' => $databasedescription,
'DB_SRV' => $sql_root['host'],
'PMA_URI' => $pma
); );
Database::pexecute($stmt, $params, true, true);
$databaseid = Database::lastInsertId();
$params['id'] = $databaseid;
// get template for mail subject // update customer usage
$mail_subject = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_subject', $replace_arr, $this->lng['mails']['new_database_by_customer']['subject']); Customers::increaseUsage($customer['customerid'], 'mysqls_used');
// get template for mail body Customers::increaseUsage($customer['customerid'], 'mysql_lastaccountnumber');
$mail_body = $this->getMailTemplate($userinfo, 'mails', 'new_database_by_customer_mailbody', $replace_arr, $this->lng['mails']['new_database_by_customer']['mailbody']);
$_mailerror = false; // send info-mail?
$mailerr_msg = ""; if ($sendinfomail == 1) {
try { $pma = $this->lng['admin']['notgiven'];
$this->mailer()->Subject = $mail_subject; if (Settings::Get('panel.phpmyadmin_url') != '') {
$this->mailer()->AltBody = $mail_body; $pma = Settings::Get('panel.phpmyadmin_url');
$this->mailer()->msgHTML(str_replace("\n", "<br />", $mail_body)); }
$this->mailer()->addAddress($userinfo['email'], \Froxlor\User::getCorrectUserSalutation($userinfo));
$this->mailer()->send(); Database::needRoot(true, $dbserver);
} catch (\PHPMailer\PHPMailer\Exception $e) { Database::needSqlData();
$mailerr_msg = $e->errorMessage(); $sql_root = Database::getSqlData();
$_mailerror = true; Database::needRoot(false);
} catch (\Exception $e) { $userinfo = $customer;
$mailerr_msg = $e->getMessage();
$_mailerror = true; $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 . "'");
if ($_mailerror) { $result = $this->apiCall('Mysqls.get', array(
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_ERR, "[API] Error sending mail: " . $mailerr_msg); 'dbname' => $username
\Froxlor\UI\Response::standard_error('errorsendingmail', $userinfo['email'], true); ));
} return $this->response(200, "successful", $result);
$this->mailer()->clearAddresses();
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] added mysql-database '" . $username . "'"); throw new \Exception("No more resources available", 406);
$result = $this->apiCall('Mysqls.get', array(
'dbname' => $username
));
return $this->response(200, "successfull", $result);
} }
/** /**
@@ -187,7 +206,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$id = $this->getParam('id', true, 0); $id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$dbname = $this->getParam('dbname', $dn_optional, ''); $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->isAdmin()) {
if ($this->getUserDetail('customers_see_all') != 1) { if ($this->getUserDetail('customers_see_all') != 1) {
@@ -254,7 +273,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Database::needRoot(false); Database::needRoot(false);
$result['size'] = $mbdata['MB'] ?? 0; $result['size'] = $mbdata['MB'] ?? 0;
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get database '" . $result['databasename'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get database '" . $result['databasename'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "dbname '" . $dbname . "'"); $key = ($id > 0 ? "id #" . $id : "dbname '" . $dbname . "'");
throw new \Exception("MySQL database with " . $key . " could not be found", 404); throw new \Exception("MySQL database with " . $key . " could not be found", 404);
@@ -274,9 +293,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param string $description * @param string $description
* optional, description for database * optional, description for database
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -287,7 +306,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$id = $this->getParam('id', true, 0); $id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$dbname = $this->getParam('dbname', $dn_optional, ''); $dbname = $this->getParam('dbname', $dn_optional, '');
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, -1);
$customer = $this->getCustomerData(); $customer = $this->getCustomerData();
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) { if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
@@ -301,13 +320,13 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
)); ));
$id = $result['id']; $id = $result['id'];
// paramters // parameters
$password = $this->getParam('mysql_password', true, ''); $password = $this->getParam('mysql_password', true, '');
$databasedescription = $this->getParam('description', true, ''); $databasedescription = $this->getParam('description', true, $result['description']);
// validation // validation
$password = \Froxlor\Validate\Validate::validate($password, 'password', '', '', array(), true); $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 != '') { if ($password != '') {
// validate password // validate password
@@ -346,7 +365,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = $this->apiCall('Mysqls.get', array( $result = $this->apiCall('Mysqls.get', array(
'dbname' => $result['databasename'] 'dbname' => $result['databasename']
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -374,7 +393,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
public function listing() public function listing()
{ {
$result = array(); $result = array();
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, -1);
$customer_ids = $this->getAllowedCustomerIds('mysql'); $customer_ids = $this->getAllowedCustomerIds('mysql');
$query_fields = array(); $query_fields = array();
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
@@ -417,14 +436,14 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Database::needRoot(false); Database::needRoot(false);
} }
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable databases * returns the total number of accessible databases
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select dbs of a specific customer by id * optional, admin-only, select dbs of a specific customer by id
@@ -444,7 +463,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_dbs']); return $this->response(200, "successful", $result['num_dbs']);
} }
} }
@@ -458,9 +477,9 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
* @param int $mysql_server * @param int $mysql_server
* optional, specify database-server, default is none * optional, specify database-server, default is none
* @param int $customerid * @param int $customerid
* optional, admin-only, the customer-id * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname * @param string $loginname
* optional, admin-only, the loginname * optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -471,7 +490,7 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$id = $this->getParam('id', true, 0); $id = $this->getParam('id', true, 0);
$dn_optional = ($id <= 0 ? false : true); $dn_optional = ($id <= 0 ? false : true);
$dbname = $this->getParam('dbname', $dn_optional, ''); $dbname = $this->getParam('dbname', $dn_optional, '');
$dbserver = $this->getParam('mysql_server', true, - 1); $dbserver = $this->getParam('mysql_server', true, -1);
$customer = $this->getCustomerData(); $customer = $this->getCustomerData();
if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) { if ($this->isAdmin() == false && Settings::IsInList('panel.customer_hide_options', 'mysql')) {
@@ -506,6 +525,6 @@ class Mysqls extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
Customers::decreaseUsage($customer['customerid'], 'mysqls_used', $resetaccnumber); Customers::decreaseUsage($customer['customerid'], 'mysqls_used', $resetaccnumber);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted database '" . $result['databasename'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted database '" . $result['databasename'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
} }

View File

@@ -59,7 +59,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
); );
$query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "` $query = "SELECT * FROM `" . TABLE_PANEL_DOMAINS . "`
WHERE `phpsettingid` = :id"; WHERE `phpsettingid` = :id AND `email_only` = '0' AND `phpenabled` = '1'";
if (! $with_subdomains) { if (! $with_subdomains) {
$query .= " AND `parentdomainid` = '0'"; $query .= " AND `parentdomainid` = '0'";
@@ -113,7 +113,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
$phpconfigs[] = $row; $phpconfigs[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($phpconfigs), 'count' => count($phpconfigs),
'list' => $phpconfigs 'list' => $phpconfigs
)); ));
@@ -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 * @access admin
* @throws \Exception * @throws \Exception
@@ -137,7 +137,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
"); ");
$result = Database::pexecute_first($result_stmt, null, true, true); $result = Database::pexecute_first($result_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_phps']); return $this->response(200, "successful", $result['num_phps']);
} }
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
@@ -165,7 +165,7 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
'id' => $id 'id' => $id
), true, true); ), true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("php-config with id #" . $id . " could not be found", 404); throw new \Exception("php-config with id #" . $id . " could not be found", 404);
} }
@@ -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 * optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
* @param string $limit_extensions * @param string $limit_extensions
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value * 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 * @access admin
* @throws \Exception * @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']); $max_requests = $this->getParam('max_requests', true, $def_fpmconfig['max_requests']);
$idle_timeout = $this->getParam('idle_timeout', true, $def_fpmconfig['idle_timeout']); $idle_timeout = $this->getParam('idle_timeout', true, $def_fpmconfig['idle_timeout']);
$limit_extensions = $this->getParam('limit_extensions', true, $def_fpmconfig['limit_extensions']); $limit_extensions = $this->getParam('limit_extensions', true, $def_fpmconfig['limit_extensions']);
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
// validation // 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); $phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
if (Settings::Get('system.mod_fcgid') == 1) { if (Settings::Get('system.mod_fcgid') == 1) {
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true)); $binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
@@ -361,13 +364,15 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
Database::pexecute($ins_stmt, $ins_data, true, true); Database::pexecute($ins_stmt, $ins_data, true, true);
$ins_data['id'] = Database::lastInsertId(); $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') . "'"); $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( $result = $this->apiCall('PhpSettings.get', array(
'id' => $ins_data['id'] 'id' => $ins_data['id']
)); ));
return $this->response(200, "successfull", $result);
$this->addForAllCustomers($allow_all_customers, $ins_data['id']);
return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); 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 * optional number of seconds for idle-timeout if FPM is used, default is fpm-daemon-value
* @param string $limit_extensions * @param string $limit_extensions
* optional limitation of php-file-extensions if FPM is used, default is fpm-daemon-value * 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 * @access admin
* @throws \Exception * @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']); $max_requests = $this->getParam('max_requests', true, $result['max_requests']);
$idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']); $idle_timeout = $this->getParam('idle_timeout', true, $result['idle_timeout']);
$limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']); $limit_extensions = $this->getParam('limit_extensions', true, $result['limit_extensions']);
$allow_all_customers = $this->getBoolParam('allow_all_customers', true, 0);
// validation // 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); $phpsettings = \Froxlor\Validate\Validate::validate(str_replace("\r\n", "\n", $phpsettings), 'phpsettings', '/^[^\0]*$/', '', array(), true);
if (Settings::Get('system.mod_fcgid') == 1) { if (Settings::Get('system.mod_fcgid') == 1) {
$binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true)); $binary = \Froxlor\FileDir::makeCorrectFile(\Froxlor\Validate\Validate::validate($binary, 'binary', '', '', array(), true));
@@ -557,13 +565,15 @@ class PhpSettings extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resour
); );
Database::pexecute($upd_stmt, $upd_data, true, true); 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') . "'"); $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( $result = $this->apiCall('PhpSettings.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result);
$this->addForAllCustomers($allow_all_customers, $id);
return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); 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 'id' => $id
), true, true); ), 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') . "'"); $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, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("Not allowed to execute given command.", 403); 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']
]);
}
}
}
} }

View File

@@ -2,6 +2,7 @@
namespace Froxlor\Api\Commands; namespace Froxlor\Api\Commands;
use Froxlor\Database\Database; use Froxlor\Database\Database;
use Froxlor\Domain\Domain;
use Froxlor\Settings; use Froxlor\Settings;
/** /**
@@ -36,7 +37,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param string $url * @param string $url
* optional, overwrites path value with an URL to generate a redirect, alternatively use the path parameter also for URLs * optional, overwrites path value with an URL to generate a redirect, alternatively use the path parameter also for URLs
* @param int $openbasedir_path * @param int $openbasedir_path
* optional, either 0 for customers-homedir or 1 for domains-docroot * optional, either 0 for domains-docroot or 1 for customers-homedir
* @param int $phpsettingid * @param int $phpsettingid
* optional, php-settings-id, if empty the $domain value is used * optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode * @param int $redirectcode
@@ -56,7 +57,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $hsts_preload * @param bool $hsts_preload
* optional whether or not to preload HSTS header value, default 0 * optional whether or not to preload HSTS header value, default 0
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -228,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 // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
if ($ssl_redirect > 0 && $letsencrypt == 1) { if ($ssl_redirect > 0 && $letsencrypt == 1) {
$ssl_redirect = 2; $ssl_redirect = 2;
@@ -250,12 +262,26 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$phpsid_result['phpsettingid'] = intval($phpsettingid); $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 // actually insert domain
$stmt = Database::prepare(" $stmt = Database::prepare("
INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET INSERT INTO `" . TABLE_PANEL_DOMAINS . "` SET
`customerid` = :customerid, `customerid` = :customerid,
`adminid` = :adminid, `adminid` = :adminid,
`domain` = :domain, `domain` = :domain,
`domain_ace` = :domain_ace,
`documentroot` = :documentroot, `documentroot` = :documentroot,
`aliasdomain` = :aliasdomain, `aliasdomain` = :aliasdomain,
`parentdomainid` = :parentdomainid, `parentdomainid` = :parentdomainid,
@@ -287,6 +313,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"customerid" => $customer['customerid'], "customerid" => $customer['customerid'],
"adminid" => $customer['adminid'], "adminid" => $customer['adminid'],
"domain" => $completedomain, "domain" => $completedomain,
"domain_ace" => $idna_convert->decode($completedomain),
"documentroot" => $path, "documentroot" => $path,
"aliasdomain" => $aliasdomain != 0 ? $aliasdomain : null, "aliasdomain" => $aliasdomain != 0 ? $aliasdomain : null,
"parentdomainid" => $domain_check['id'], "parentdomainid" => $domain_check['id'],
@@ -332,9 +359,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
\Froxlor\Domain\Domain::addRedirectToDomain($subdomain_id, $redirectcode); \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 // 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'); Customers::increaseUsage($customer['customerid'], 'subdomains_used');
@@ -343,7 +370,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = $this->apiCall('SubDomains.get', array( $result = $this->apiCall('SubDomains.get', array(
'id' => $subdomain_id 'id' => $subdomain_id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
throw new \Exception("No more resources available", 406); throw new \Exception("No more resources available", 406);
} }
@@ -407,7 +434,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
); );
} }
} else { } else {
if (Settings::IsInList('panel.customer_hide_options', 'domains')) { if (! $this->isInternal() && Settings::IsInList('panel.customer_hide_options', 'domains')) {
throw new \Exception("You cannot access this resource", 405); throw new \Exception("You cannot access this resource", 405);
} }
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
@@ -424,7 +451,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] get subdomain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
$key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'"); $key = ($id > 0 ? "id #" . $id : "domainname '" . $domainname . "'");
throw new \Exception("Subdomain with " . $key . " could not be found", 404); throw new \Exception("Subdomain with " . $key . " could not be found", 404);
@@ -448,7 +475,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $isemaildomain * @param bool $isemaildomain
* optional * optional
* @param int $openbasedir_path * @param int $openbasedir_path
* optional, either 0 for customers-homedir or 1 for domains-docroot * optional, either 0 for domains-docroot or 1 for customers-homedir
* @param int $phpsettingid * @param int $phpsettingid
* optional, php-settings-id, if empty the $domain value is used * optional, php-settings-id, if empty the $domain value is used
* @param int $redirectcode * @param int $redirectcode
@@ -468,7 +495,9 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* @param bool $hsts_preload * @param bool $hsts_preload
* optional whether or not to preload HSTS header value * optional whether or not to preload HSTS header value
* @param int $customerid * @param int $customerid
* required when called as admin, not needed when called as customer * optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -589,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 // We can't enable let's encrypt for wildcard-domains
if ($iswildcarddomain == '1' && $letsencrypt == '1') { 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 // Temporarily deactivate ssl_redirect until Let's Encrypt certificate was generated
@@ -613,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']) . "'"); $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 // handle redirect
if ($_doredirect) { if ($_doredirect) {
\Froxlor\Domain\Domain::updateRedirectOfDomain($id, $redirectcode); \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(" $stmt = Database::prepare("
UPDATE `" . TABLE_PANEL_DOMAINS . "` SET UPDATE `" . TABLE_PANEL_DOMAINS . "` SET
`documentroot` = :documentroot, `documentroot` = :documentroot,
@@ -681,17 +732,19 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
Database::pexecute($del_stmt, array( Database::pexecute($del_stmt, array(
'id' => $id 'id' => $id
), true, true); ), true, true);
// remove domain from acme.sh / lets encrypt if used
\Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::DELETE_DOMAIN_SSL, $result['domain']);
} }
\Froxlor\System\Cronjob::inserttask('1'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_VHOST);
\Froxlor\System\Cronjob::inserttask('4'); \Froxlor\System\Cronjob::inserttask(\Froxlor\Cron\TaskId::REBUILD_DNS);
$idna_convert = new \Froxlor\Idna\IdnaWrapper(); $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']) . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_INFO, "[API] edited domain '" . $idna_convert->decode($result['domain']) . "'");
} }
$result = $this->apiCall('SubDomains.get', array( $result = $this->apiCall('SubDomains.get', array(
'id' => $id 'id' => $id
)); ));
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**
@@ -765,6 +818,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'`d`.`id`', '`d`.`id`',
'`d`.`customerid`', '`d`.`customerid`',
'`d`.`domain`', '`d`.`domain`',
'`d`.`domain_ace`',
'`d`.`documentroot`', '`d`.`documentroot`',
'`d`.`isbinddomain`', '`d`.`isbinddomain`',
'`d`.`isemaildomain`', '`d`.`isemaildomain`',
@@ -780,7 +834,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
// prepare select statement // prepare select statement
$domains_stmt = Database::prepare(" $domains_stmt = Database::prepare("
SELECT " . implode(",", $select_fields) . ", IF(`d`.`parentdomainid` > 0, `pd`.`domain`, `d`.`domain`) AS `parentdomainname`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias` SELECT " . implode(",", $select_fields) . ", IF(`d`.`parentdomainid` > 0, `pd`.`domain_ace`, `d`.`domain_ace`) AS `parentdomainname`, `ad`.`id` AS `aliasdomainid`, `ad`.`domain` AS `aliasdomain`, `da`.`id` AS `domainaliasid`, `da`.`domain` AS `domainalias`
FROM `" . TABLE_PANEL_DOMAINS . "` `d` FROM `" . TABLE_PANEL_DOMAINS . "` `d`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `ad` ON `d`.`aliasdomain`=`ad`.`id`
LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id` LEFT JOIN `" . TABLE_PANEL_DOMAINS . "` `da` ON `da`.`aliasdomain`=`d`.`id`
@@ -794,14 +848,14 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
while ($row = $domains_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($row = $domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$result[] = $row; $result[] = $row;
} }
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
} }
/** /**
* returns the total number of accessable subdomain entries * returns the total number of accessible subdomain entries
* *
* @param int $customerid * @param int $customerid
* optional, admin-only, select (sub)domains of a specific customer by id * optional, admin-only, select (sub)domains of a specific customer by id
@@ -859,7 +913,7 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
"); ");
$result = Database::pexecute_first($domains_stmt, null, true, true); $result = Database::pexecute_first($domains_stmt, null, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_subdom']); return $this->response(200, "successful", $result['num_subdom']);
} }
} }
@@ -870,6 +924,10 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
* optional, the domain-id * optional, the domain-id
* @param string $domainname * @param string $domainname
* optional, the domainname * optional, the domainname
* @param int $customerid
* optional, required when called as admin (if $loginname is not specified)
* @param string $loginname
* optional, required when called as admin (if $customerid is not specified)
* *
* @access admin, customer * @access admin, customer
* @throws \Exception * @throws \Exception
@@ -961,19 +1019,19 @@ class SubDomains extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\Resourc
'domainid' => $id 'domainid' => $id
), true, true); ), 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 // 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 // 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 // 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 // reduce subdomain-usage-counter
Customers::decreaseUsage($customer['customerid'], 'subdomains_used'); Customers::decreaseUsage($customer['customerid'], 'subdomains_used');
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted subdomain '" . $result['domain'] . "'"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] deleted subdomain '" . $result['domain'] . "'");
return $this->response(200, "successfull", $result); return $this->response(200, "successful", $result);
} }
/** /**

View File

@@ -74,7 +74,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list log-entries"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list log-entries");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));
@@ -129,7 +129,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$result = Database::pexecute_first($result_stmt, $params, true, true); $result = Database::pexecute_first($result_stmt, $params, true, true);
if ($result) { if ($result) {
return $this->response(200, "successfull", $result['num_logs']); return $this->response(200, "successful", $result['num_logs']);
} }
} }
@@ -204,7 +204,7 @@ class SysLog extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEnt
$params['trunc'] = $truncatedate; $params['trunc'] = $truncatedate;
Database::pexecute($result_stmt, $params, true, true); Database::pexecute($result_stmt, $params, true, true);
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] truncated the froxlor syslog"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_WARNING, "[API] truncated the froxlor syslog");
return $this->response(200, "successfull", true); return $this->response(200, "successful", true);
} }
throw new \Exception("Not allowed to execute given command.", 403); throw new \Exception("Not allowed to execute given command.", 403);
} }

View File

@@ -60,6 +60,10 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
* optional, default empty * optional, default empty
* @param int $day * @param int $day
* optional, default empty * optional, default empty
* @param int $date_from
* optional timestamp, default empty, if specified, $year, $month and $day will be ignored
* @param int $date_until
* optional timestamp, default empty, if specified, $year, $month and $day will be ignored
* @param bool $customer_traffic * @param bool $customer_traffic
* optional, admin-only, whether to output ones own traffic or all of ones customers, default is 0 (false) * optional, admin-only, whether to output ones own traffic or all of ones customers, default is 0 (false)
* @param int $customerid * @param int $customerid
@@ -76,10 +80,29 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$year = $this->getParam('year', true, ""); $year = $this->getParam('year', true, "");
$month = $this->getParam('month', true, ""); $month = $this->getParam('month', true, "");
$day = $this->getParam('day', true, ""); $day = $this->getParam('day', true, "");
$date_from = $this->getParam('date_from', true, - 1);
$date_until = $this->getParam('date_until', true, - 1);
$customer_traffic = $this->getBoolParam('customer_traffic', true, 0); $customer_traffic = $this->getBoolParam('customer_traffic', true, 0);
$customer_ids = $this->getAllowedCustomerIds(); $customer_ids = $this->getAllowedCustomerIds();
$result = array(); $result = array();
$params = array(); $params = array();
// validate parameters
if ($date_from >= 0 || $date_until >= 0) {
$year = "";
$month = "";
$day = "";
if ($date_from == $date_until) {
$date_until = -1;
}
if ($date_from >= 0 && $date_until >= 0 && $date_until < $date_from) {
// switch
$temp_ts = $date_from;
$date_from = $date_until;
$date_until = $temp_ts;
}
}
// check for year/month/day // check for year/month/day
$where_str = ""; $where_str = "";
if (! empty($year) && is_numeric($year)) { if (! empty($year) && is_numeric($year)) {
@@ -94,6 +117,17 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$where_str .= " AND `day` = :day"; $where_str .= " AND `day` = :day";
$params['day'] = $day; $params['day'] = $day;
} }
if ($date_from >= 0 && $date_until >= 0) {
$where_str .= " AND `stamp` BETWEEN :df AND :du";
$params['df'] = $date_from;
$params['du'] = $date_until;
} elseif ($date_from >= 0 && $date_until < 0) {
$where_str .= " AND `stamp` > :df";
$params['df'] = $date_from;
} elseif ($date_from < 0 && $date_until >= 0) {
$where_str .= " AND `stamp` < :du";
$params['du'] = $date_until;
}
if (! $this->isAdmin() || ($this->isAdmin() && $customer_traffic)) { if (! $this->isAdmin() || ($this->isAdmin() && $customer_traffic)) {
$result_stmt = Database::prepare(" $result_stmt = Database::prepare("
@@ -110,7 +144,7 @@ class Traffic extends \Froxlor\Api\ApiCommand implements \Froxlor\Api\ResourceEn
$result[] = $row; $result[] = $row;
} }
$this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list traffic"); $this->logger()->logAction($this->isAdmin() ? \Froxlor\FroxlorLogger::ADM_ACTION : \Froxlor\FroxlorLogger::USR_ACTION, LOG_NOTICE, "[API] list traffic");
return $this->response(200, "successfull", array( return $this->response(200, "successful", array(
'count' => count($result), 'count' => count($result),
'list' => $result 'list' => $result
)); ));

View File

@@ -56,7 +56,7 @@ class FroxlorRPC
private static function validateAuth($key, $secret) private static function validateAuth($key, $secret)
{ {
$sel_stmt = \Froxlor\Database\Database::prepare(" $sel_stmt = \Froxlor\Database\Database::prepare("
SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed SELECT ak.*, a.api_allowed as admin_api_allowed, c.api_allowed as cust_api_allowed, c.deactivated
FROM `api_keys` ak FROM `api_keys` ak
LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid LEFT JOIN `panel_admins` a ON a.adminid = ak.adminid
LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid LEFT JOIN `panel_customers` c ON c.customerid = ak.customerid
@@ -67,7 +67,7 @@ class FroxlorRPC
'as' => $secret 'as' => $secret
), true, true); ), true, true);
if ($result) { if ($result) {
if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1))) { if ($result['apikey'] == $key && $result['secret'] == $secret && ($result['valid_until'] == - 1 || $result['valid_until'] >= time()) && (($result['customerid'] == 0 && $result['admin_api_allowed'] == 1) || ($result['customerid'] > 0 && $result['cust_api_allowed'] == 1 && $result['deactivated'] == 0))) {
// get user to check whether api call is allowed // get user to check whether api call is allowed
if (! empty($result['allowed_from'])) { if (! empty($result['allowed_from'])) {
// @todo allow specification and validating of whole subnets later // @todo allow specification and validating of whole subnets later

View File

@@ -35,20 +35,6 @@ abstract class BulkAction
*/ */
private $impFile = null; private $impFile = null;
/**
* customer id of the user the entity is being added to
*
* @var int
*/
private $custId = null;
/**
* array of customer data read from the database
*
* @var array
*/
private $custData = null;
/** /**
* api-function to call for addingg entity * api-function to call for addingg entity
* *
@@ -70,20 +56,27 @@ abstract class BulkAction
*/ */
private $errors = array(); private $errors = array();
/**
* logged in user
*
* @var array
*/
protected $userinfo = array();
/** /**
* class constructor, optionally sets file and customer-id * class constructor, optionally sets file and customer-id
* *
* @param string $import_file * @param string $import_file
* @param int $customer_id * @param array $userinfo
* *
* @return object BulkAction instance * @return object BulkAction instance
*/ */
protected function __construct($import_file = null, $customer_id = 0) protected function __construct($import_file = null, $userinfo = array())
{ {
if (! empty($import_file)) { if (! empty($import_file)) {
$this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file); $this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
} }
$this->custId = $customer_id; $this->userinfo = $userinfo;
} }
/** /**
@@ -109,18 +102,6 @@ abstract class BulkAction
$this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file); $this->impFile = \Froxlor\FileDir::makeCorrectFile($import_file);
} }
/**
* setter for customer-id
*
* @param int $customer_id
*
* @return void
*/
public function setCustomer($customer_id = 0)
{
$this->custId = $customer_id;
}
/** /**
* return the list of errors * return the list of errors
* *
@@ -145,21 +126,21 @@ abstract class BulkAction
protected function importEntity($data_array = null) protected function importEntity($data_array = null)
{ {
global $userinfo; if (empty($data_array)) return null;
$module = '\\Froxlor\\Api\\Commands\\' . substr($this->api_call, 0, strpos($this->api_call, ".")); $module = '\\Froxlor\\Api\\Commands\\' . substr($this->api_call, 0, strpos($this->api_call, "."));
$function = substr($this->api_call, strpos($this->api_call, ".") + 1); $function = substr($this->api_call, strpos($this->api_call, ".") + 1);
$new_data = array(); $new_data = array();
foreach ($this->api_params as $idx => $param) { 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]; $new_data[$param] = $data_array[$idx];
} }
} }
$result = null; $result = null;
try { try {
$json_result = $module::getLocal($userinfo, $new_data)->$function(); $json_result = $module::getLocal($this->userinfo, $new_data)->$function();
$result = json_decode($json_result, true)['data']; $result = json_decode($json_result, true)['data'];
} catch (\Exception $e) { } catch (\Exception $e) {
$this->errors[] = $e->getMessage(); $this->errors[] = $e->getMessage();
@@ -169,7 +150,7 @@ abstract class BulkAction
/** /**
* reads in the csv import file and returns an array with * 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 * @param string $separator
* *
@@ -189,6 +170,10 @@ abstract class BulkAction
throw new \Exception("Unable to read file '" . $this->impFile . "'"); throw new \Exception("Unable to read file '" . $this->impFile . "'");
} }
if (empty($separator) || strlen($separator) != 1) {
throw new \Exception("Invalid separator specified: '" . $separator . "'");
}
$file_data = array(); $file_data = array();
$is_params_line = true; $is_params_line = true;
$fh = @fopen($this->impFile, "r"); $fh = @fopen($this->impFile, "r");
@@ -218,37 +203,4 @@ abstract class BulkAction
return $file_data; return $file_data;
} }
/**
* to be called first in doImport() to read in customer and entity data
*/
protected function preImport()
{
$this->readCustomerData();
if ($this->custId <= 0) {
throw new \Exception("Invalid customer selected");
}
if (is_null($this->custData)) {
throw new \Exception("Failed to read customer data");
}
}
/**
* reads customer data from panel_customer by $_custId
*
* @return bool
*/
protected function readCustomerData()
{
$cust_stmt = \Froxlor\Database\Database::prepare("SELECT * FROM `" . TABLE_PANEL_CUSTOMERS . "` WHERE `customerid` = :cid");
$this->custData = \Froxlor\Database\Database::pexecute_first($cust_stmt, array(
'cid' => $this->custId
));
if (is_array($this->custData) && isset($this->custData['customerid']) && $this->custData['customerid'] == $this->custId) {
return true;
}
$this->custData = null;
return false;
}
} }

View File

@@ -32,9 +32,9 @@ class DomainBulkAction extends BulkAction
* *
* @return object DomainBulkAction instance * @return object DomainBulkAction instance
*/ */
public function __construct($import_file = null, $customer_id = 0) public function __construct($import_file = null, $userinfo)
{ {
parent::__construct($import_file, $customer_id); parent::__construct($import_file, $userinfo);
$this->setApiCall('Domains.add'); $this->setApiCall('Domains.add');
} }
@@ -49,23 +49,14 @@ class DomainBulkAction extends BulkAction
*/ */
public function doImport($separator = ";", $offset = 0) public function doImport($separator = ";", $offset = 0)
{ {
$this->preImport(); if ($this->userinfo['domains'] == "-1") {
// get the admins userinfo to check for domains_used, etc.
global $userinfo;
if ($userinfo['domains'] == "-1") {
$dom_unlimited = true; $dom_unlimited = true;
} else { } else {
$dom_unlimited = false; $dom_unlimited = false;
} }
$domains_used = (int) $userinfo['domains_used']; $domains_used = (int) $this->userinfo['domains_used'];
$domains_avail = (int) $userinfo['domains']; $domains_avail = (int) $this->userinfo['domains'];
if (empty($separator) || strlen($separator) != 1) {
throw new \Exception("Invalid separator specified: '" . $separator . "'");
}
if (! is_int($offset) || $offset < 0) { if (! is_int($offset) || $offset < 0) {
throw new \Exception("Invalid offset specified"); throw new \Exception("Invalid offset specified");

View File

@@ -26,11 +26,16 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
*/ */
private function validate() private function validate()
{ {
global $lng;
$this->checkConfigParam(true); $this->checkConfigParam(true);
$this->parseConfig(); $this->parseConfig();
require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php'; require FROXLOR_INSTALL_DIR . '/lib/tables.inc.php';
include_once FROXLOR_INSTALL_DIR . '/lng/english.lng.php';
include_once FROXLOR_INSTALL_DIR . '/lng/lng_references.php';
if (array_key_exists("import-settings", $this->_args)) { if (array_key_exists("import-settings", $this->_args)) {
$this->importSettings(); $this->importSettings();
} }
@@ -78,6 +83,20 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
$distros = glob($config_dir . '*.xml'); $distros = glob($config_dir . '*.xml');
// tmp array // tmp array
$distributions_select_data = array(); $distributions_select_data = array();
//set default os.
$os_dist = array('ID' => 'bullseye');
$os_version = array('0' => '11');
$os_default = $os_dist['ID'];
//read os-release
if(file_exists('/etc/os-release')) {
$os_dist = parse_ini_file('/etc/os-release', false);
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];
}
}
// read in all the distros // read in all the distros
foreach ($distros as $_distribution) { foreach ($distros as $_distribution) {
// get configparser object // get configparser object
@@ -86,6 +105,12 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
$dist_display = $this->getCompleteDistroName($dist); $dist_display = $this->getCompleteDistroName($dist);
// store in tmp array // store in tmp array
$distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution))); $distributions_select_data[$dist_display] = str_replace(".xml", "", strtolower(basename($_distribution)));
//guess if this is the current distro.
$ver = explode('.', $dist->distributionVersion)[0];
if (strtolower($os_dist['ID']) == strtolower($dist->distributionName) && $os_version == $ver) {
$os_default = str_replace(".xml", "", strtolower(basename($_distribution)));
}
} }
// sort by distribution name // sort by distribution name
@@ -103,7 +128,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
echo PHP_EOL; echo PHP_EOL;
while (! in_array($_daemons_config['distro'], $distributions_select_data)) { while (! in_array($_daemons_config['distro'], $distributions_select_data)) {
$_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", "buster"); $_daemons_config['distro'] = ConfigServicesCmd::getInput("choose distribution", $os_default);
} }
// go through all services and let user check whether to include it or not // go through all services and let user check whether to include it or not
@@ -316,13 +341,43 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
// try to convert namserver hosts to ip's // try to convert namserver hosts to ip's
$ns_ips = ""; $ns_ips = "";
$known_ns_ips = [];
if (Settings::Get('system.nameservers') != '') { if (Settings::Get('system.nameservers') != '') {
$nameservers = explode(',', Settings::Get('system.nameservers')); $nameservers = explode(',', Settings::Get('system.nameservers'));
foreach ($nameservers as $nameserver) { foreach ($nameservers as $nameserver) {
$nameserver = trim($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); $nameserver_ips = \Froxlor\PhpHelper::gethostbynamel6($nameserver);
if (is_array($nameserver_ips) && count($nameserver_ips) > 0) { // append dot to hostname
$ns_ips .= implode(",", $nameserver_ips); 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);
} }
} }
} }
@@ -340,7 +395,6 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
'<SERVERIP>' => Settings::Get('system.ipaddress'), '<SERVERIP>' => Settings::Get('system.ipaddress'),
'<NAMESERVERS>' => Settings::Get('system.nameservers'), '<NAMESERVERS>' => Settings::Get('system.nameservers'),
'<NAMESERVERS_IP>' => $ns_ips, '<NAMESERVERS_IP>' => $ns_ips,
'<AXFRSERVERS>' => Settings::Get('system.axfrservers'),
'<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'), '<VIRTUAL_MAILBOX_BASE>' => Settings::Get('system.vmail_homedir'),
'<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'), '<VIRTUAL_UID_MAPS>' => Settings::Get('system.vmail_uid'),
'<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'), '<VIRTUAL_GID_MAPS>' => Settings::Get('system.vmail_gid'),
@@ -377,7 +431,7 @@ class ConfigServicesAction extends \Froxlor\Cli\Action
} elseif (! file_exists($this->_args["froxlor-dir"])) { } elseif (! file_exists($this->_args["froxlor-dir"])) {
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')"); throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
} elseif (! is_readable($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"] . "')");
} }
} }
} }

View 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"] . "')");
}
}
}
}

View File

@@ -62,7 +62,7 @@ class SwitchServerIpAction extends \Froxlor\Cli\Action
$ip_list = $this->_args['switch']; $ip_list = $this->_args['switch'];
if (empty($ip_list) || is_bool($ip_list)) { 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(); $ips_to_switch = array();
@@ -179,7 +179,7 @@ class SwitchServerIpAction extends \Froxlor\Cli\Action
} elseif (! file_exists($this->_args["froxlor-dir"])) { } elseif (! file_exists($this->_args["froxlor-dir"])) {
throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')"); throw new \Exception("Given froxlor directory cannot be found ('" . $this->_args["froxlor-dir"] . "')");
} elseif (! is_readable($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"] . "')");
} }
} }
} }

View 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
}
}

View File

@@ -55,7 +55,7 @@ class ConfigDaemon
private $isparsed = false; 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 * @var \SimpleXMLElement
*/ */

View File

@@ -39,6 +39,13 @@ class ConfigParser
*/ */
private $services = array(); private $services = array();
/**
* Holding the available defaults in the XML
*
* @var array
*/
private $defaults = array();
/** /**
* Store the parsed SimpleXMLElement for usage * Store the parsed SimpleXMLElement for usage
* *
@@ -147,7 +154,7 @@ class ConfigParser
* *
* @return bool * @return bool
*/ */
private function parse() private function parseServices()
{ {
// We only want to parse the stuff one time // We only want to parse the stuff one time
if ($this->isparsed == true) { if ($this->isparsed == true) {
@@ -174,6 +181,29 @@ class ConfigParser
return true; return true;
} }
/**
* Parse the XML and populate $this->services
*
* @return bool
*/
private function parseDefaults()
{
// We only want to parse the stuff one time
if ($this->isparsed == true) {
return true;
}
// Get all defaults
$defaults = $this->xml->xpath('//defaults');
foreach ($defaults as $default) {
$this->defaults = $default;
}
// Switch flag to indicate we parsed our data
$this->isparsed = true;
return true;
}
/** /**
* Return all services defined by the XML * Return all services defined by the XML
* *
@@ -184,9 +214,25 @@ class ConfigParser
public function getServices() public function getServices()
{ {
// Let's parse this shit(!) // Let's parse this shit(!)
$this->parse(); $this->parseServices();
// Return our carefully searched for services // Return our carefully searched for services
return $this->services; return $this->services;
} }
/**
* Return all defaults defined by the XML
*
* The array will hold ConfigDefaults - Objects for further handling
*
* @return array
*/
public function getDefaults()
{
// Let's parse this shit(!)
$this->parseDefaults();
// Return our carefully searched for defaults
return $this->defaults;
}
} }

View File

@@ -99,7 +99,7 @@ class CronConfig
$binpath = Settings::Get("system.croncmdline"); $binpath = Settings::Get("system.croncmdline");
// fallback as it is important // fallback as it is important
if ($binpath === null) { if ($binpath === null) {
$binpath = "/usr/bin/nice -n 5 /usr/bin/php5 -q"; $binpath = "/usr/bin/nice -n 5 /usr/bin/php -q";
} }
$cronfile .= "root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n"; $cronfile .= "root " . $binpath . " " . \Froxlor\FileDir::makeCorrectFile(\Froxlor\Froxlor::getInstallDir() . "/scripts/froxlor_master_cronjob.php") . " --" . $row_cronentry['cronfile'] . " 1> /dev/null\n";

View File

@@ -41,6 +41,7 @@ abstract class DnsBase
{ {
$this->logger = $logger; $this->logger = $logger;
$known_ns_ips = [];
if (Settings::Get('system.nameservers') != '') { if (Settings::Get('system.nameservers') != '') {
$nameservers = explode(',', Settings::Get('system.nameservers')); $nameservers = explode(',', Settings::Get('system.nameservers'));
foreach ($nameservers as $nameserver) { foreach ($nameservers as $nameserver) {
@@ -58,6 +59,8 @@ abstract class DnsBase
$nameserver_ips = array( $nameserver_ips = array(
$nameserver $nameserver
); );
} else {
$known_ns_ips = array_merge($known_ns_ips, $nameserver_ips);
} }
$this->ns[] = array( $this->ns[] = array(
'hostname' => $nameserver, 'hostname' => $nameserver,
@@ -80,7 +83,9 @@ abstract class DnsBase
if (Settings::Get('system.axfrservers') != '') { if (Settings::Get('system.axfrservers') != '') {
$axfrservers = explode(',', Settings::Get('system.axfrservers')); $axfrservers = explode(',', Settings::Get('system.axfrservers'));
foreach ($axfrservers as $axfrserver) { foreach ($axfrservers as $axfrserver) {
$this->axfr[] = trim($axfrserver); if (!in_array(trim($axfrserver), $known_ns_ips)) {
$this->axfr[] = trim($axfrserver);
}
} }
} }
} }
@@ -195,18 +200,18 @@ abstract class DnsBase
while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) { while ($domain = $result_domains_stmt->fetch(\PDO::FETCH_ASSOC)) {
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']); $privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public'); $pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') { if ($domain['dkim_privkey'] == '' || $domain['dkim_pubkey'] == '') {
$max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`"); $max_dkim_id_stmt = Database::query("SELECT MAX(`dkim_id`) as `max_dkim_id` FROM `" . TABLE_PANEL_DOMAINS . "`");
$max_dkim_id = $max_dkim_id_stmt->fetch(\PDO::FETCH_ASSOC); $max_dkim_id = $max_dkim_id_stmt->fetch(\PDO::FETCH_ASSOC);
$domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1; $domain['dkim_id'] = (int) $max_dkim_id['max_dkim_id'] + 1;
$privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id']); $privkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . Settings::Get('dkim.privkeysuffix'));
\Froxlor\FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength')); \Froxlor\FileDir::safe_exec('openssl genrsa -out ' . escapeshellarg($privkey_filename) . ' ' . Settings::Get('dkim.dkim_keylength'));
$domain['dkim_privkey'] = file_get_contents($privkey_filename); $domain['dkim_privkey'] = file_get_contents($privkey_filename);
\Froxlor\FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename)); \Froxlor\FileDir::safe_exec("chmod 0640 " . escapeshellarg($privkey_filename));
$pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim_' . $domain['dkim_id'] . '.public'); $pubkey_filename = \Froxlor\FileDir::makeCorrectFile(Settings::Get('dkim.dkim_prefix') . '/dkim' . $domain['dkim_id'] . '.public');
\Froxlor\FileDir::safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename)); \Froxlor\FileDir::safe_exec('openssl rsa -in ' . escapeshellarg($privkey_filename) . ' -pubout -outform pem -out ' . escapeshellarg($pubkey_filename));
$domain['dkim_pubkey'] = file_get_contents($pubkey_filename); $domain['dkim_pubkey'] = file_get_contents($pubkey_filename);
\Froxlor\FileDir::safe_exec("chmod 0664 " . escapeshellarg($pubkey_filename)); \Froxlor\FileDir::safe_exec("chmod 0664 " . escapeshellarg($pubkey_filename));

View File

@@ -1,6 +1,8 @@
<?php <?php
namespace Froxlor\Cron\Dns; namespace Froxlor\Cron\Dns;
use Froxlor\Settings;
/** /**
* This file is part of the Froxlor project. * This file is part of the Froxlor project.
* Copyright (c) 2016 the Froxlor Team (see authors). * 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); $pdns_domain = $pdns_domains_stmt->fetch(\PDO::FETCH_ASSOC);
$del_rec_stmt->execute(array( if ($pdns_domain && ! empty($pdns_domain['id'])) {
'did' => $pdns_domain['id'] $del_rec_stmt->execute(array(
)); 'did' => $pdns_domain['id']
$del_meta_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'] $del_dom_stmt->execute(array(
)); 'did' => $pdns_domain['id']
));
}
} }
} }
private function insertZone($domainname, $serial = 0) private function insertZone($domainname, $serial = 0)
{ {
$ins_stmt = \Froxlor\Dns\PowerDNS::getDB()->prepare(" $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( $ins_stmt->execute(array(
'domainname' => $domainname, 'domainname' => $domainname,
'serial' => $serial 'serial' => $serial,
'type' => strtoupper(Settings::Get('system.powerdns_mode'))
)); ));
$lastid = \Froxlor\Dns\PowerDNS::getDB()->lastInsertId(); $lastid = \Froxlor\Dns\PowerDNS::getDB()->lastInsertId();
return $lastid; return $lastid;

View File

@@ -172,7 +172,7 @@ class Apache extends HttpConfigBase
$mypath = $this->getMyPath($row_ipsandports); $mypath = $this->getMyPath($row_ipsandports);
$this->virtualhosts_data[$vhosts_filename] .= 'DocumentRoot "' . $mypath . '"' . "\n"; $this->virtualhosts_data[$vhosts_filename] .= 'DocumentRoot "' . rtrim($mypath, "/") . '"' . "\n";
if ($row_ipsandports['vhostcontainer_servername_statement'] == '1') { if ($row_ipsandports['vhostcontainer_servername_statement'] == '1') {
$this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= ' ServerName ' . Settings::Get('system.hostname') . "\n";
@@ -413,7 +413,8 @@ class Apache extends HttpConfigBase
$this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n"; $this->virtualhosts_data[$vhosts_filename] .= $this->processSpecialConfigTemplate($row_ipsandports['ssl_specialsettings'], $domain, $row_ipsandports['ip'], $row_ipsandports['port'], $row_ipsandports['ssl'] == '1') . "\n";
} }
if ($row_ipsandports['ssl_cert_file'] == '') { // check for required fallback
if (($row_ipsandports['ssl_cert_file'] == '' || ! file_exists($row_ipsandports['ssl_cert_file'])) && (Settings::Get('system.le_froxlor_enabled') == '0' || $this->froxlorVhostHasLetsEncryptCert() == false)) {
$row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file'); $row_ipsandports['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($row_ipsandports['ssl_cert_file'])) { if (! file_exists($row_ipsandports['ssl_cert_file'])) {
// explicitly disable ssl for this vhost // explicitly disable ssl for this vhost
@@ -424,6 +425,11 @@ class Apache extends HttpConfigBase
if ($row_ipsandports['ssl_key_file'] == '') { if ($row_ipsandports['ssl_key_file'] == '') {
$row_ipsandports['ssl_key_file'] = Settings::Get('system.ssl_key_file'); $row_ipsandports['ssl_key_file'] = Settings::Get('system.ssl_key_file');
if (! file_exists($row_ipsandports['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$row_ipsandports['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . Settings::Get('system.hostname') . '"');
}
} }
if ($row_ipsandports['ssl_ca_file'] == '') { if ($row_ipsandports['ssl_ca_file'] == '') {
@@ -559,7 +565,7 @@ class Apache extends HttpConfigBase
* *
* @return string * @return string
*/ */
protected function composePhpOptions($domain, $ssl_vhost = false) protected function composePhpOptions(&$domain, $ssl_vhost = false)
{ {
$php_options_text = ''; $php_options_text = '';
@@ -661,7 +667,7 @@ class Apache extends HttpConfigBase
if ($domain['deactivated'] == '1' && Settings::Get('system.deactivateddocroot') != '') { if ($domain['deactivated'] == '1' && Settings::Get('system.deactivateddocroot') != '') {
$webroot_text .= ' # Using docroot for deactivated users...' . "\n"; $webroot_text .= ' # Using docroot for deactivated users...' . "\n";
$webroot_text .= ' DocumentRoot "' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')) . "\"\n"; $webroot_text .= ' DocumentRoot "' . rtrim(\Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')), "/") . "\"\n";
$webroot_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')) . '">' . "\n"; $webroot_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir(Settings::Get('system.deactivateddocroot')) . '">' . "\n";
// >=apache-2.4 enabled? // >=apache-2.4 enabled?
if (Settings::Get('system.apache24') == '1') { if (Settings::Get('system.apache24') == '1') {
@@ -674,7 +680,7 @@ class Apache extends HttpConfigBase
$webroot_text .= ' </Directory>' . "\n"; $webroot_text .= ' </Directory>' . "\n";
$this->deactivated = true; $this->deactivated = true;
} else { } else {
$webroot_text .= ' DocumentRoot "' . $domain['documentroot'] . "\"\n"; $webroot_text .= ' DocumentRoot "' . rtrim($domain['documentroot'], "/") . "\"\n";
$this->deactivated = false; $this->deactivated = false;
} }
@@ -782,14 +788,6 @@ class Apache extends HttpConfigBase
)); ));
$logfiles_text .= ' CustomLog "|' . $command . '" ' . $logtype . "\n"; $logfiles_text .= ' CustomLog "|' . $command . '" ' . $logtype . "\n";
} else { } else {
// Create the logfile if it does not exist (fixes #46)
touch($error_log);
chown($error_log, Settings::Get('system.httpuser'));
chgrp($error_log, Settings::Get('system.httpgroup'));
touch($access_log);
chown($access_log, Settings::Get('system.httpuser'));
chgrp($access_log, Settings::Get('system.httpgroup'));
$logfiles_text .= ' ErrorLog "' . $error_log . '"' . "\n"; $logfiles_text .= ' ErrorLog "' . $error_log . '"' . "\n";
$logfiles_text .= ' CustomLog "' . $access_log . '" ' . $logtype . "\n"; $logfiles_text .= ' CustomLog "' . $access_log . '" ' . $logtype . "\n";
} }
@@ -828,7 +826,7 @@ class Apache extends HttpConfigBase
// After inserting the AWStats information, // After inserting the AWStats information,
// be sure to build the awstats conf file as well // be sure to build the awstats conf file as well
// and chown it using $awstats_params, #258 // 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); \Froxlor\Http\Statistics::createAWStatsConf(Settings::Get('system.logfiles_directory') . $domain['loginname'] . $speciallogfile . '-access.log', $domain['domain'], $alias . $server_alias, $domain['customerroot'], $domain);
} }
} }
@@ -950,7 +948,7 @@ class Apache extends HttpConfigBase
} }
if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') { if ($ssl_vhost === true && $domain['ssl'] == '1' && Settings::Get('system.use_ssl') == '1') {
if ($domain['ssl_cert_file'] == '') { if ($domain['ssl_cert_file'] == '' || ! file_exists($domain['ssl_cert_file'])) {
$domain['ssl_cert_file'] = Settings::Get('system.ssl_cert_file'); $domain['ssl_cert_file'] = Settings::Get('system.ssl_cert_file');
if (! file_exists($domain['ssl_cert_file'])) { if (! file_exists($domain['ssl_cert_file'])) {
// explicitly disable ssl for this vhost // explicitly disable ssl for this vhost
@@ -959,8 +957,13 @@ class Apache extends HttpConfigBase
} }
} }
if ($domain['ssl_key_file'] == '') { if ($domain['ssl_key_file'] == '' || ! file_exists($domain['ssl_key_file'])) {
$domain['ssl_key_file'] = Settings::Get('system.ssl_key_file'); $domain['ssl_key_file'] = Settings::Get('system.ssl_key_file');
if (! file_exists($domain['ssl_key_file'])) {
// explicitly disable ssl for this vhost
$domain['ssl_cert_file'] = "";
\Froxlor\FroxlorLogger::getInstanceOf()->logAction(\Froxlor\FroxlorLogger::CRON_ACTION, LOG_DEBUG, 'System certificate key-file "' . Settings::Get('system.ssl_key_file') . '" does not seem to exist. Disabling SSL-vhost for "' . $domain['domain'] . '"');
}
} }
if ($domain['ssl_ca_file'] == '') { if ($domain['ssl_ca_file'] == '') {

View File

@@ -24,7 +24,7 @@ use Froxlor\Cron\Http\Php\PhpInterface;
class ApacheFcgi extends Apache class ApacheFcgi extends Apache
{ {
protected function composePhpOptions($domain, $ssl_vhost = false) protected function composePhpOptions(&$domain, $ssl_vhost = false)
{ {
$php_options_text = ''; $php_options_text = '';
@@ -43,6 +43,8 @@ class ApacheFcgi extends Apache
$php_options_text .= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n"; $php_options_text .= ' SuexecUserGroup "' . $domain['loginname'] . '" "' . $domain['loginname'] . '"' . "\n";
} }
$domain['fpm_socket'] = $php->getInterface()->getSocketFile();
// mod_proxy stuff for apache-2.4 // mod_proxy stuff for apache-2.4
if (Settings::Get('system.apache24') == '1' && Settings::Get('phpfpm.use_mod_proxy') == '1') { if (Settings::Get('system.apache24') == '1' && Settings::Get('phpfpm.use_mod_proxy') == '1') {
$filesmatch = $phpconfig['fpm_settings']['limit_extensions']; $filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
@@ -54,7 +56,9 @@ class ApacheFcgi extends Apache
// start block, cut off last pipe and close block // start block, cut off last pipe and close block
$filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')'; $filesmatch = '(' . str_replace(".", "\.", substr($filesmatch, 0, - 1)) . ')';
$php_options_text .= ' <FilesMatch \.' . $filesmatch . '$>' . "\n"; $php_options_text .= ' <FilesMatch \.' . $filesmatch . '$>' . "\n";
$php_options_text .= ' SetHandler proxy:unix:' . $php->getInterface()->getSocketFile() . '|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"; $php_options_text .= ' </FilesMatch>' . "\n";
$mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']); $mypath_dir = new \Froxlor\Http\Directory($domain['documentroot']);
@@ -80,7 +84,7 @@ class ApacheFcgi extends Apache
if ($phpconfig['pass_authorizationheader'] == '1') { if ($phpconfig['pass_authorizationheader'] == '1') {
$addheader = " -pass-header Authorization"; $addheader = " -pass-header Authorization";
} }
$php_options_text .= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $php->getInterface()->getSocketFile() . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n"; $php_options_text .= ' FastCgiExternalServer ' . $php->getInterface()->getAliasConfigDir() . $srvName . ' -socket ' . $domain['fpm_socket'] . ' -idle-timeout ' . $phpconfig['fpm_settings']['idle_timeout'] . $addheader . "\n";
$php_options_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n"; $php_options_text .= ' <Directory "' . \Froxlor\FileDir::makeCorrectDir($domain['documentroot']) . '">' . "\n";
$filesmatch = $phpconfig['fpm_settings']['limit_extensions']; $filesmatch = $phpconfig['fpm_settings']['limit_extensions'];
$extensions = explode(" ", $filesmatch); $extensions = explode(" ", $filesmatch);

View File

@@ -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 * @param string $group
* settings-group * settings-group

View File

@@ -105,7 +105,11 @@ class DomainSSL
$_fh = fopen($filename, 'w'); $_fh = fopen($filename, 'w');
fwrite($_fh, $dom_certs[$type]); fwrite($_fh, $dom_certs[$type]);
fclose($_fh); fclose($_fh);
chmod($filename, 0600); if ($type == 'ssl_key_file') {
chmod($filename, 0600);
} else {
chmod($filename, 0644);
}
} }
} }
// override corresponding array values // override corresponding array values

View File

@@ -98,8 +98,12 @@ class HttpConfigBase
'IP' => $ip, 'IP' => $ip,
'PORT' => $port, 'PORT' => $port,
'SCHEME' => ($is_ssl_vhost) ? 'https' : 'http', 'SCHEME' => ($is_ssl_vhost) ? 'https' : 'http',
'DOCROOT' => $domain['documentroot'] 'DOCROOT' => $domain['documentroot'],
'FPMSOCKET' => ''
); );
if ((int) Settings::Get('phpfpm.enabled') == 1 && isset($domain['fpm_socket']) && !empty($domain['fpm_socket'])) {
$templateVars['FPMSOCKET'] = $domain['fpm_socket'];
}
return \Froxlor\PhpHelper::replaceVariables($template, $templateVars); return \Froxlor\PhpHelper::replaceVariables($template, $templateVars);
} }

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