Till Brehm
2014-09-01 2066766a3e12ba9ae46f0534c715ec6a6dccbe3c
commit | author | age
46c683 1 <?php
T 2
3 /*
cea1e5 4 Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
46c683 5 All rights reserved.
T 6
7 Redistribution and use in source and binary forms, with or without modification,
8 are permitted provided that the following conditions are met:
9
10     * Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12     * Redistributions in binary form must reproduce the above copyright notice,
13       this list of conditions and the following disclaimer in the documentation
14       and/or other materials provided with the distribution.
15     * Neither the name of ISPConfig nor the names of its contributors
16       may be used to endorse or promote products derived from this software without
17       specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
26 OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 class apache2_plugin {
ac933e 32
46c683 33     var $plugin_name = 'apache2_plugin';
T 34     var $class_name = 'apache2_plugin';
ac933e 35
46c683 36     // private variables
T 37     var $action = '';
481c00 38     var $ssl_certificate_changed = false;
ac933e 39
46c683 40     //* This function is called during ispconfig installation to determine
T 41     //  if a symlink shall be created for this plugin.
42     function onInstall() {
43         global $conf;
ac933e 44
46c683 45         if($conf['services']['web'] == true) {
T 46             return true;
47         } else {
48             return false;
49         }
ac933e 50
46c683 51     }
ac933e 52
V 53
46c683 54     /*
T 55          This function is called when the plugin is loaded
56     */
ac933e 57
46c683 58     function onLoad() {
T 59         global $app;
ac933e 60
46c683 61         /*
T 62         Register for the events
63         */
7fe908 64         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl');
MC 65         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl');
66         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl');
ac933e 67
7fe908 68         $app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert');
MC 69         $app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update');
70         $app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete');
ac933e 71
7fe908 72         $app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip');
MC 73         $app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip');
74         $app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip');
ac933e 75
7fe908 76         $app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav');
MC 77         $app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav');
78         $app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav');
79
80         $app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');
81
82         $app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user');
83         $app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user');
84         $app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user');
85
86         $app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update');
87         $app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete');
88
89         $app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete');
90
46c683 91     }
ac933e 92
46c683 93     // Handle the creation of SSL certificates
7fe908 94     function ssl($event_name, $data) {
46c683 95         global $app, $conf;
7fe908 96
c77103 97         $app->uses('system');
1a2310 98
L 99         // load the server configuration options
100         $app->uses('getconf');
101         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
102         if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
7fe908 103             $app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);
MC 104
1ca823 105         //* Only vhosts can have a ssl cert
6fb93d 106         if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain") return;
ac933e 107
c77103 108         // if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
T 109         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
7fe908 110
fb3339 111         $ssl_dir = $data['new']['document_root'].'/ssl';
J 112         $domain = $data['new']['ssl_domain'];
113         $key_file = $ssl_dir.'/'.$domain.'.key.org';
114         $key_file2 = $ssl_dir.'/'.$domain.'.key';
115         $csr_file = $ssl_dir.'/'.$domain.'.csr';
116         $crt_file = $ssl_dir.'/'.$domain.'.crt';
ac933e 117
4bd960 118         //* Create a SSL Certificate, but only if this is not a mirror server.
T 119         if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
7fe908 120
481c00 121             $this->ssl_certificate_changed = true;
7fe908 122
e94a9f 123             //* Rename files if they exist
43b345 124             if(file_exists($key_file)){
7fe908 125                 $app->system->rename($key_file, $key_file.'.bak');
MC 126                 $app->system->chmod($key_file.'.bak', 0400);
43b345 127             }
T 128             if(file_exists($key_file2)){
7fe908 129                 $app->system->rename($key_file2, $key_file2.'.bak');
MC 130                 $app->system->chmod($key_file2.'.bak', 0400);
43b345 131             }
7fe908 132             if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
MC 133             if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');
134
fb3339 135             $rand_file = $ssl_dir.'/random_file';
7fe908 136             $rand_data = md5(uniqid(microtime(), 1));
ac933e 137             for($i=0; $i<1000; $i++) {
7fe908 138                 $rand_data .= md5(uniqid(microtime(), 1));
MC 139                 $rand_data .= md5(uniqid(microtime(), 1));
140                 $rand_data .= md5(uniqid(microtime(), 1));
141                 $rand_data .= md5(uniqid(microtime(), 1));
ac933e 142             }
c77103 143             $app->system->file_put_contents($rand_file, $rand_data);
46c683 144
7fe908 145             $ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15);
ac933e 146
46c683 147             $ssl_cnf = "        RANDFILE               = $rand_file
T 148
149         [ req ]
6d80f5 150         default_bits           = 2048
46c683 151         default_keyfile        = keyfile.pem
T 152         distinguished_name     = req_distinguished_name
153         attributes             = req_attributes
154         prompt                 = no
155         output_password        = $ssl_password
156
157         [ req_distinguished_name ]
e94a9f 158         C                      = ".trim($data['new']['ssl_country'])."
T 159         ST                     = ".trim($data['new']['ssl_state'])."
160         L                      = ".trim($data['new']['ssl_locality'])."
161         O                      = ".trim($data['new']['ssl_organisation'])."
162         OU                     = ".trim($data['new']['ssl_organisation_unit'])."
46c683 163         CN                     = $domain
T 164         emailAddress           = webmaster@".$data['new']['domain']."
165
166         [ req_attributes ]
167         challengePassword              = A challenge password";
ac933e 168
fb3339 169             $ssl_cnf_file = $ssl_dir.'/openssl.conf';
7fe908 170             $app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
ac933e 171
46c683 172             $rand_file = escapeshellcmd($rand_file);
T 173             $key_file = escapeshellcmd($key_file);
8c82ef 174             $openssl_cmd_key_file = $key_file;
992797 175             if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
46c683 176             $key_file2 = escapeshellcmd($key_file2);
8c82ef 177             $openssl_cmd_key_file2 = $key_file2;
992797 178             if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
46c683 179             $ssl_days = 3650;
T 180             $csr_file = escapeshellcmd($csr_file);
8c82ef 181             $openssl_cmd_csr_file = $csr_file;
992797 182             if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
46c683 183             $config_file = escapeshellcmd($ssl_cnf_file);
T 184             $crt_file = escapeshellcmd($crt_file);
8c82ef 185             $openssl_cmd_crt_file = $crt_file;
992797 186             if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
46c683 187
c77103 188             if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
7fe908 189
8c82ef 190                 exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
FT 191                 exec("openssl req -new -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -out $openssl_cmd_csr_file -days $ssl_days -config $config_file");
192                 exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
1a2310 193
L 194                 if(file_exists($web_config['CA_path'].'/openssl.cnf'))
5c4d55 195                 {
8c82ef 196                     exec("openssl ca -batch -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file");
7fe908 197                     $app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
8c82ef 198                     if (filesize($crt_file)==0 || !file_exists($crt_file)) $app->log("CA-Certificate signing failed.  openssl ca -out $openssl_cmd_crt_file -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -in $openssl_cmd_csr_file", LOGLEVEL_ERROR);
1a2310 199                 };
723662 200                 if (@filesize($crt_file)==0 || !file_exists($crt_file)){
8c82ef 201                     exec("openssl req -x509 -passin pass:$ssl_password -passout pass:$ssl_password -key $openssl_cmd_key_file -in $openssl_cmd_csr_file -out $openssl_cmd_crt_file -days $ssl_days -config $config_file ");
7fe908 202                     $app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
5c4d55 203                 };
7fe908 204
ac933e 205             }
46c683 206
7fe908 207             $app->system->chmod($key_file, 0400);
MC 208             $app->system->chmod($key_file2, 0400);
c77103 209             @$app->system->unlink($config_file);
T 210             @$app->system->unlink($rand_file);
211             $ssl_request = $app->db->quote($app->system->file_get_contents($csr_file));
212             $ssl_cert = $app->db->quote($app->system->file_get_contents($crt_file));
0d20af 213             $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
d1086f 214             /* Update the DB of the (local) Server */
0d20af 215             $app->db->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 216             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 217             /* Update also the master-DB of the Server-Farm */
0d20af 218             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '$ssl_request', ssl_cert = '$ssl_cert', ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
fb3339 219             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
46c683 220         }
ac933e 221
46c683 222         //* Save a SSL certificate to disk
9f56bd 223         if($data["new"]["ssl_action"] == 'save') {
481c00 224             $this->ssl_certificate_changed = true;
9f56bd 225             $ssl_dir = $data["new"]["document_root"]."/ssl";
edf806 226             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
481c00 227             $key_file = $ssl_dir.'/'.$domain.'.key.org';
0d20af 228             $key_file2 = $ssl_dir.'/'.$domain.'.key';
9f56bd 229             $csr_file = $ssl_dir.'/'.$domain.".csr";
T 230             $crt_file = $ssl_dir.'/'.$domain.".crt";
231             $bundle_file = $ssl_dir.'/'.$domain.".bundle";
7fe908 232
481c00 233             //* Backup files
43b345 234             if(file_exists($key_file)){
7fe908 235                 $app->system->copy($key_file, $key_file.'~');
MC 236                 $app->system->chmod($key_file.'~', 0400);
43b345 237             }
T 238             if(file_exists($key_file2)){
7fe908 239                 $app->system->copy($key_file2, $key_file2.'~');
MC 240                 $app->system->chmod($key_file2.'~', 0400);
43b345 241             }
7fe908 242             if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~');
MC 243             if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~');
244             if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~');
245
481c00 246             //* Write new ssl files
7fe908 247             if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
MC 248             if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
249             if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
250
72695f 251             //* Write the key file, if field is empty then import the key into the db
T 252             if(trim($data["new"]["ssl_key"]) != '') {
7fe908 253                 $app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
MC 254                 $app->system->chmod($key_file2, 0400);
72695f 255             } else {
T 256                 $ssl_key2 = $app->db->quote($app->system->file_get_contents($key_file2));
257                 /* Update the DB of the (local) Server */
258                 $app->db->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
259                 /* Update also the master-DB of the Server-Farm */
260                 $app->dbmaster->query("UPDATE web_domain SET ssl_key = '$ssl_key2' WHERE domain = '".$data['new']['domain']."'");
261             }
7fe908 262
d1086f 263             /* Update the DB of the (local) Server */
fb3339 264             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 265
d1086f 266             /* Update also the master-DB of the Server-Farm */
fb3339 267             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 268             $app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 269         }
ac933e 270
46c683 271         //* Delete a SSL certificate
fb3339 272         if($data['new']['ssl_action'] == 'del') {
J 273             $ssl_dir = $data['new']['document_root'].'/ssl';
edf806 274             $domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
fb3339 275             $csr_file = $ssl_dir.'/'.$domain.'.csr';
J 276             $crt_file = $ssl_dir.'/'.$domain.'.crt';
277             $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
c77103 278             if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
7fe908 279             {
8c82ef 280                 exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
7fe908 281                 $app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
MC 282             };
c77103 283             $app->system->unlink($csr_file);
T 284             $app->system->unlink($crt_file);
285             $app->system->unlink($bundle_file);
d1086f 286             /* Update the DB of the (local) Server */
fb3339 287             $app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 288             $app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
d1086f 289             /* Update also the master-DB of the Server-Farm */
fb3339 290             $app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = '".$data['new']['domain']."'");
J 291             $app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = '".$data['new']['domain']."'");
7fe908 292             $app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
46c683 293         }
ac933e 294
46c683 295     }
ac933e 296
V 297
7fe908 298     function insert($event_name, $data) {
46c683 299         global $app, $conf;
ac933e 300
46c683 301         $this->action = 'insert';
T 302         // just run the update function
7fe908 303         $this->update($event_name, $data);
ac933e 304
V 305
46c683 306     }
ac933e 307
V 308
7fe908 309     function update($event_name, $data) {
46c683 310         global $app, $conf;
ac933e 311
46c683 312         if($this->action != 'insert') $this->action = 'update';
ac933e 313
6fb93d 314         if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['parent_domain_id'] > 0) {
ac933e 315
fb3339 316             $old_parent_domain_id = intval($data['old']['parent_domain_id']);
J 317             $new_parent_domain_id = intval($data['new']['parent_domain_id']);
ac933e 318
1ca823 319             // If the parent_domain_id has been changed, we will have to update the old site as well.
fb3339 320             if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
J 321                 $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$old_parent_domain_id." AND active = 'y'");
322                 $data['new'] = $tmp;
323                 $data['old'] = $tmp;
46c683 324                 $this->action = 'update';
7fe908 325                 $this->update($event_name, $data);
46c683 326             }
ac933e 327
46c683 328             // This is not a vhost, so we need to update the parent record instead.
fb3339 329             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$new_parent_domain_id." AND active = 'y'");
J 330             $data['new'] = $tmp;
331             $data['old'] = $tmp;
46c683 332             $this->action = 'update';
T 333         }
ac933e 334
46c683 335         // load the server configuration options
fb3339 336         $app->uses('getconf');
J 337         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 338
2bbc4c 339         //* Check if this is a chrooted setup
155cc0 340         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 341             $apache_chrooted = true;
7fe908 342             $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
2bbc4c 343         } else {
T 344             $apache_chrooted = false;
345         }
ac933e 346
fb3339 347         if($data['new']['document_root'] == '') {
7fe908 348             if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') $app->log('document_root not set', LOGLEVEL_WARN);
46c683 349             return 0;
T 350         }
15687e 351         if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
TB 352             || $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
353             $app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
46c683 354             return 0;
T 355         }
e94a9f 356         if(trim($data['new']['domain']) == '') {
7fe908 357             $app->log('domain is empty', LOGLEVEL_WARN);
e94a9f 358             return 0;
T 359         }
7fe908 360
MC 361         $web_folder = 'web';
362         $log_folder = 'log';
79d955 363         $old_web_folder = 'web';
MC 364         $old_log_folder = 'log';
7fe908 365         if($data['new']['type'] == 'vhostsubdomain') {
79d955 366             // new one
7fe908 367             $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['new']['parent_domain_id']));
MC 368             $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
369             if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
370             $web_folder = $data['new']['web_folder'];
371             $log_folder .= '/' . $subdomain_host;
372             unset($tmp);
79d955 373             
MC 374             if(isset($data['old']['parent_domain_id'])) {
375                 // old one
376                 $tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
377                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
378                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
379                 $old_web_folder = $data['old']['web_folder'];
380                 $old_log_folder .= '/' . $subdomain_host;
381                 unset($tmp);
382             }
7fe908 383         }
6fb93d 384
dba68f 385         // Create group and user, if not exist
T 386         $app->uses('system');
7fe908 387
8cf78b 388         if($web_config['connect_userid_to_webid'] == 'y') {
T 389             //* Calculate the uid and gid
390             $connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
391             $fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
392             $fixed_uid_param = '--uid '.$fixed_uid_gid;
393             $fixed_gid_param = '--gid '.$fixed_uid_gid;
7fe908 394
8cf78b 395             //* Check if a ispconfigend user and group exists and create them
T 396             if(!$app->system->is_group('ispconfigend')) {
397                 exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
398             }
399             if(!$app->system->is_user('ispconfigend')) {
400                 exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
401             }
402         } else {
403             $fixed_uid_param = '';
404             $fixed_gid_param = '';
405         }
dba68f 406
T 407         $groupname = escapeshellcmd($data['new']['system_group']);
408         if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
8cf78b 409             exec('groupadd '.$fixed_gid_param.' '.$groupname);
dba68f 410             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
7fe908 411             $app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG);
dba68f 412         }
T 413
414         $username = escapeshellcmd($data['new']['system_user']);
415         if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
8cf78b 416             if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 417                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
418                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
419             } else {
420                 exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
421                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
422             }
7fe908 423             $app->log('Adding the user: '.$username, LOGLEVEL_DEBUG);
dba68f 424         }
ac933e 425
46c683 426         //* If the client of the site has been changed, we have a change of the document root
fb3339 427         if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
ac933e 428
46c683 429             //* Get the old client ID
fb3339 430             $old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
J 431             $old_client_id = intval($old_client['client_id']);
46c683 432             unset($old_client);
ac933e 433
46c683 434             //* Remove the old symlinks
7fe908 435             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 436             if(is_array($tmp_symlinks_array)) {
T 437                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 438                     $tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink);
MC 439                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 440                     // Remove trailing slash
T 441                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
442                     // create the symlinks, if not exist
436975 443                     if(is_link($tmp_symlink)) {
fb3339 444                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 445                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 446                     }
T 447                 }
448             }
7fe908 449
4b9329 450             //* Remove protection of old folders
7fe908 451             $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 452
7fe908 453             if($data["new"]["type"] != "vhostsubdomain") {
MC 454                 //* Move the site data
455                 $tmp_docroot = explode('/', $data['new']['document_root']);
456                 unset($tmp_docroot[count($tmp_docroot)-1]);
457                 $new_dir = implode('/', $tmp_docroot);
ac933e 458
7fe908 459                 $tmp_docroot = explode('/', $data['old']['document_root']);
MC 460                 unset($tmp_docroot[count($tmp_docroot)-1]);
461                 $old_dir = implode('/', $tmp_docroot);
ac933e 462
7fe908 463                 //* Check if there is already some data in the new docroot and rename it as we need a clean path to move the existing site to the new path
MC 464                 if(@is_dir($data['new']['document_root'])) {
465                     $app->system->web_folder_protection($data['new']['document_root'], false);
466                     $app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
467                     $app->log('Renaming existing directory in new docroot location. mv '.$data['new']['document_root'].' '.$data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'), LOGLEVEL_DEBUG);
468                 }
3fb802 469                 
TB 470                 //* Unmount the old log directory bfore we move the log dir
471                 exec('umount '.escapeshellcmd($old_dir.'/log'));
ac933e 472
7fe908 473                 //* Create new base directory, if it does not exist yet
MC 474                 if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
475                 $app->system->web_folder_protection($data['old']['document_root'], false);
476                 exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
477                 //$app->system->rename($data['old']['document_root'],$new_dir);
478                 $app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG);
0930f5 479
7fe908 480                 // Handle the change in php_open_basedir
MC 481                 $data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']);
482
483                 //* Change the owner of the website files to the new website owner
484                 exec('chown --recursive --from='.escapeshellcmd($data['old']['system_user']).':'.escapeshellcmd($data['old']['system_group']).' '.escapeshellcmd($data['new']['system_user']).':'.escapeshellcmd($data['new']['system_group']).' '.$new_dir);
485
486                 //* Change the home directory and group of the website user
487                 $command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod';
488                 $command .= ' --home '.escapeshellcmd($data['new']['document_root']);
489                 $command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
490                 $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
491                 exec($command);
492             }
493
fb3339 494             if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
7fe908 495
10b4c8 496             //* Change the log mount
79d955 497             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 498             $app->system->removeLine('/etc/fstab', $fstab_line);
79d955 499             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
ff5b86 500             $app->system->removeLine('/etc/fstab', $fstab_line);
TB 501             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
7fe908 502             $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
3fb802 503             
TB 504             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
ac933e 505
46c683 506         }
ac933e 507
46c683 508         //print_r($data);
ac933e 509
fb3339 510         // Check if the directories are there and create them if necessary.
7fe908 511         $app->system->web_folder_protection($data['new']['document_root'], false);
MC 512
6fb93d 513         if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
M 514         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
515         //if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
c77103 516         if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
T 517         if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
518         if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
519         if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
7fe908 520
d87f76 521         //* Create the new private directory
T 522         if(!is_dir($data['new']['document_root'].'/private')) {
523             $app->system->mkdirpath($data['new']['document_root'].'/private');
7fe908 524             $app->system->chmod($data['new']['document_root'].'/private', 0710);
MC 525             $app->system->chown($data['new']['document_root'].'/private', $username);
526             $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
d87f76 527         }
7fe908 528
MC 529
46c683 530         // Remove the symlink for the site, if site is renamed
fb3339 531         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
J 532             if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
79d955 533             if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
7fe908 534
10b4c8 535             //* remove old log mount
79d955 536             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
7fe908 537             $app->system->removeLine('/etc/fstab', $fstab_line);
MC 538
10b4c8 539             //* Unmount log directory
79d955 540             exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
46c683 541         }
7fe908 542
d5a517 543         //* Create the log dir if nescessary and mount it
10b4c8 544         if(!is_dir($data['new']['document_root'].'/'.$log_folder) || !is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain']) || is_link($data['new']['document_root'].'/'.$log_folder)) {
6fb93d 545             if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
10b4c8 546             if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
c3bf39 547             $app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
7fe908 548             $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root');
MC 549             $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root');
550             $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 551             exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
d5a517 552             //* add mountpoint to fstab
ff5b86 553             $fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
7fe908 554             $app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
d5a517 555         }
7fe908 556
MC 557         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 558
46c683 559         // Get the client ID
fb3339 560         $client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['new']['sys_groupid']));
J 561         $client_id = intval($client['client_id']);
46c683 562         unset($client);
ac933e 563
46c683 564         // Remove old symlinks, if site is renamed
fb3339 565         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
7fe908 566             $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 567             if(is_array($tmp_symlinks_array)) {
T 568                 foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 569                     $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 570                     $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
46c683 571                     // Remove trailing slash
T 572                     if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
573                     // remove the symlinks, if not exist
574                     if(is_link($tmp_symlink)) {
fb3339 575                         exec('rm -f '.escapeshellcmd($tmp_symlink));
7fe908 576                         $app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 577                     }
T 578                 }
579             }
580         }
ac933e 581
46c683 582         // Create the symlinks for the sites
7fe908 583         $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
46c683 584         if(is_array($tmp_symlinks_array)) {
T 585             foreach($tmp_symlinks_array as $tmp_symlink) {
7fe908 586                 $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
MC 587                 $tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink);
46c683 588                 // Remove trailing slash
T 589                 if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
590                 //* Remove symlink if target folder has been changed.
fb3339 591                 if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
c77103 592                     $app->system->unlink($tmp_symlink);
46c683 593                 }
T 594                 // create the symlinks, if not exist
595                 if(!is_link($tmp_symlink)) {
7fe908 596                     //     exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
552178 597                     if ($web_config["website_symlinks_rel"] == 'y') {
M 598                         $this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
599                     } else {
600                         exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
601                     }
602
7fe908 603                     $app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG);
46c683 604                 }
T 605             }
606         }
ac933e 607
V 608
3e41e8 609
7fe908 610         // Install the Standard or Custom Error, Index and other related files
MC 611         // /usr/local/ispconfig/server/conf is for the standard files
612         // /usr/local/ispconfig/server/conf-custom is for the custom files
613         // setting a local var here
614
615         // normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
6fb93d 616         if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
7fe908 617
MC 618             // Copy the error pages
fb3339 619             if($data['new']['errordocs']) {
6fb93d 620                 $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 621                 if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 622                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 623                 }
T 624                 else {
4ffb51 625                     if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 626                         exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 627                     }
T 628                     else {
7fe908 629                         exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 630                     }
T 631                 }
fb3339 632                 exec('chmod -R a+r '.$error_page_path);
46c683 633             }
T 634
7fe908 635             if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 636                 exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
637
638                 if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
639                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
640                 }
641                 if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
642                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
643                 }
644                 if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
645                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
646                 }
647             }
46c683 648             else {
4ffb51 649                 if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
6fb93d 650                     exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
46c683 651                 }
T 652                 else {
7fe908 653                     exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
6fb93d 654                     if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
M 655                     if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
656                     if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
46c683 657                 }
T 658             }
6fb93d 659             exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
ac933e 660
V 661             //** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
6fb93d 662         } elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
7fe908 663
6fb93d 664             $error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
7fe908 665             if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
MC 666                 exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 667             }
T 668             else {
4ffb51 669                 if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
F 670                     exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
46c683 671                 }
T 672                 else {
7fe908 673                     exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
46c683 674                 }
T 675             }
fb3339 676             exec('chmod -R a+r '.$error_page_path);
5d5d88 677             exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
46c683 678         }  // end copy error docs
ac933e 679
cc6568 680         // Set the quota for the user, but only for vhosts, not vhostsubdomains
H 681         if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
fb3339 682             if($data['new']['hd_quota'] > 0) {
J 683                 $blocks_soft = $data['new']['hd_quota'] * 1024;
ac933e 684                 $blocks_hard = $blocks_soft + 1024;
V 685             } else {
686                 $blocks_soft = $blocks_hard = 0;
687             }
46c683 688             exec("setquota -u $username $blocks_soft $blocks_hard 0 0 -a &> /dev/null");
fb3339 689             exec('setquota -T -u '.$username.' 604800 604800 -a &> /dev/null');
46c683 690         }
ac933e 691
1ca823 692         if($this->action == 'insert' || $data["new"]["system_user"] != $data["old"]["system_user"]) {
46c683 693             // Chown and chmod the directories below the document root
6fb93d 694             $this->_exec('chown -R '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 695             // The document root itself has to be owned by root in normal level and by the web owner in security level 20
T 696             if($web_config['security_level'] == 20) {
6fb93d 697                 $this->_exec('chown '.$username.':'.$groupname.' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 698             } else {
6fb93d 699                 $this->_exec('chown root:root '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder);
8db8f3 700             }
46c683 701         }
7fe908 702
615a0a 703         //* add the Apache user to the client group if this is a vhost and security level is set to high, no matter if this is an insert or update and regardless of set_folder_permissions_on_update
T 704         if($data['new']['type'] == 'vhost' && $web_config['security_level'] == 20) $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
ac933e 705
8db8f3 706         //* If the security level is set to high
8cf78b 707         if(($this->action == 'insert' && $data['new']['type'] == 'vhost') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhost')) {
7fe908 708
MC 709             $app->system->web_folder_protection($data['new']['document_root'], false);
710
d87f76 711             //* Check if we have the new private folder and create it if nescessary
T 712             if(!is_dir($data['new']['document_root'].'/private')) $app->system->mkdir($data['new']['document_root'].'/private');
7fe908 713
edf806 714             if($web_config['security_level'] == 20) {
7fe908 715
MC 716                 $app->system->chmod($data['new']['document_root'], 0755);
7c37ed 717                 $app->system->chmod($data['new']['document_root'].'/web', 0711);
7fe908 718                 $app->system->chmod($data['new']['document_root'].'/webdav', 0710);
MC 719                 $app->system->chmod($data['new']['document_root'].'/private', 0710);
720                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
ac933e 721
edf806 722                 // make tmp directory writable for Apache and the website users
5aedfd 723                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 724
cea1e5 725                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 726                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 727                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
c77103 728                 }
7fe908 729
8cf78b 730                 if($web_config['add_web_users_to_sshusers_group'] == 'y') {
T 731                     $command = 'usermod';
732                     $command .= ' --groups sshusers';
526b99 733                     $command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
8cf78b 734                     $this->_exec($command);
T 735                 }
ac933e 736
edf806 737                 //* if we have a chrooted Apache environment
T 738                 if($apache_chrooted) {
739                     $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
ac933e 740
edf806 741                     //* add the apache user to the client group in the chroot environment
T 742                     $tmp_groupfile = $app->system->server_conf['group_datei'];
743                     $app->system->server_conf['group_datei'] = $web_config['website_basedir'].'/etc/group';
744                     $app->system->add_user_to_group($groupname, escapeshellcmd($web_config['user']));
745                     $app->system->server_conf['group_datei'] = $tmp_groupfile;
746                     unset($tmp_groupfile);
747                 }
7fe908 748
8cf78b 749                 //* Chown all default directories
7fe908 750                 $app->system->chown($data['new']['document_root'], 'root');
MC 751                 $app->system->chgrp($data['new']['document_root'], 'root');
752                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
753                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 754                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 755                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 756                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 757                 }
7fe908 758                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
MC 759                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
760                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
761                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
762                 $app->system->chown($data['new']['document_root'].'/web', $username);
763                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
764                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
765                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
766                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
767                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
768                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
769                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
770                 $app->system->chown($data['new']['document_root'].'/private', $username);
771                 $app->system->chgrp($data['new']['document_root'].'/private', $groupname);
ac933e 772
edf806 773                 // If the security Level is set to medium
T 774             } else {
775
7fe908 776                 $app->system->chmod($data['new']['document_root'], 0755);
MC 777                 $app->system->chmod($data['new']['document_root'].'/web', 0755);
778                 $app->system->chmod($data['new']['document_root'].'/webdav', 0755);
779                 $app->system->chmod($data['new']['document_root'].'/ssl', 0755);
780                 $app->system->chmod($data['new']['document_root'].'/cgi-bin', 0755);
781
edf806 782                 // make temp directory writable for Apache and the website users
5aedfd 783                 $app->system->chmod($data['new']['document_root'].'/tmp', 0770);
7fe908 784
6fb93d 785                 // Set Log directory to 755 to make the logs accessible by the FTP user
418b41 786                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 787                     $app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
6fb93d 788                 }
7fe908 789
MC 790                 $app->system->chown($data['new']['document_root'], 'root');
791                 $app->system->chgrp($data['new']['document_root'], 'root');
792                 $app->system->chown($data['new']['document_root'].'/cgi-bin', $username);
793                 $app->system->chgrp($data['new']['document_root'].'/cgi-bin', $groupname);
418b41 794                 if(realpath($data['new']['document_root'].'/'.$log_folder . '/error.log') == '/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log') {
7fe908 795                     $app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root', false);
MC 796                     $app->system->chgrp($data['new']['document_root'].'/'.$log_folder, $groupname, false);
c77103 797                 }
7fe908 798
MC 799                 $app->system->chown($data['new']['document_root'].'/ssl', 'root');
800                 $app->system->chgrp($data['new']['document_root'].'/ssl', 'root');
801                 $app->system->chown($data['new']['document_root'].'/tmp', $username);
802                 $app->system->chgrp($data['new']['document_root'].'/tmp', $groupname);
803                 $app->system->chown($data['new']['document_root'].'/web', $username);
804                 $app->system->chgrp($data['new']['document_root'].'/web', $groupname);
805                 $app->system->chown($data['new']['document_root'].'/web/error', $username);
806                 $app->system->chgrp($data['new']['document_root'].'/web/error', $groupname);
807                 $app->system->chown($data['new']['document_root'].'/web/stats', $username);
808                 $app->system->chgrp($data['new']['document_root'].'/web/stats', $groupname);
809                 $app->system->chown($data['new']['document_root'].'/webdav', $username);
810                 $app->system->chgrp($data['new']['document_root'].'/webdav', $groupname);
8db8f3 811             }
6fb93d 812         } elseif(($this->action == 'insert' && $data['new']['type'] == 'vhostsubdomain') or ($web_config['set_folder_permissions_on_update'] == 'y' && $data['new']['type'] == 'vhostsubdomain')) {
M 813             if($web_config['security_level'] == 20) {
7fe908 814                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0710);
MC 815                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
816                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
817                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
818                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
819                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
820                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
821             } else {
822                 $app->system->chmod($data['new']['document_root'].'/' . $web_folder, 0755);
823                 $app->system->chown($data['new']['document_root'].'/' . $web_folder, $username);
824                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder, $groupname);
825                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/error', $username);
826                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/error', $groupname);
827                 $app->system->chown($data['new']['document_root'].'/' . $web_folder . '/stats', $username);
828                 $app->system->chgrp($data['new']['document_root'].'/' . $web_folder . '/stats', $groupname);
829             }
830         }
831
4b9329 832         //* Protect web folders
7fe908 833         $app->system->web_folder_protection($data['new']['document_root'], true);
ac933e 834
6fb93d 835         if($data['new']['type'] == 'vhost') {
7fe908 836             // Change the ownership of the error log to the root user
MC 837             if(!@is_file('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log')) exec('touch '.escapeshellcmd('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log'));
838             $app->system->chown('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
839             $app->system->chgrp('/var/log/ispconfig/httpd/'.$data['new']['domain'].'/error.log', 'root');
840         }
ac933e 841
26c0fc 842         //* Write the custom php.ini file, if custom_php_ini fieled is not empty
fb3339 843         $custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$data['new']['system_user'];
7fe908 844         if($data['new']['type'] == 'vhostsubdomain') $custom_php_ini_dir .= '_' . $web_folder;
c77103 845         if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');
7fe908 846
26c0fc 847         //* add open_basedir restriction to custom php.ini content, required for suphp only
7fe908 848         if(!stristr($data['new']['custom_php_ini'], 'open_basedir') && $data['new']['php'] == 'suphp') {
26c0fc 849             $data['new']['custom_php_ini'] .= "\nopen_basedir = '".$data['new']['php_open_basedir']."'\n";
T 850         }
7fe908 851
cc6568 852         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
7fe908 853
cc6568 854         if(trim($data['new']['fastcgi_php_version']) != ''){
H 855             list($custom_fastcgi_php_name, $custom_fastcgi_php_executable, $custom_fastcgi_php_ini_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
856             if(is_file($custom_fastcgi_php_ini_dir)) $custom_fastcgi_php_ini_dir = dirname($custom_fastcgi_php_ini_dir);
7fe908 857             if(substr($custom_fastcgi_php_ini_dir, -1) == '/') $custom_fastcgi_php_ini_dir = substr($custom_fastcgi_php_ini_dir, 0, -1);
cc6568 858         }
H 859
26c0fc 860         //* Create custom php.ini
fb3339 861         if(trim($data['new']['custom_php_ini']) != '') {
7fddfe 862             $has_custom_php_ini = true;
3f478f 863             if(!is_dir($custom_php_ini_dir)) $app->system->mkdirpath($custom_php_ini_dir);
7fddfe 864             $php_ini_content = '';
fb3339 865             if($data['new']['php'] == 'mod') {
7fddfe 866                 $master_php_ini_path = $web_config['php_ini_path_apache'];
T 867             } else {
cc6568 868                 if($data["new"]['php'] == 'fast-cgi') {
H 869                     if(trim($data['new']['fastcgi_php_version']) != '' && file_exists($custom_fastcgi_php_ini_dir)){
870                         $master_php_ini_path = $custom_fastcgi_php_ini_dir;
871                     } elseif(file_exists($fastcgi_config["fastcgi_phpini_path"])){
872                         $master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
873                     } else {
874                         $master_php_ini_path = $web_config['php_ini_path_cgi'];
875                     }
9f56bd 876                 } else {
T 877                     $master_php_ini_path = $web_config['php_ini_path_cgi'];
878                 }
7fddfe 879             }
7fe908 880
72695f 881             //* Add php.ini to the path in case that the master_php_ini_path is a directory
T 882             if($master_php_ini_path != '' && is_dir($master_php_ini_path) && is_file($master_php_ini_path.'/php.ini')) {
7fe908 883                 if(substr($master_php_ini_path, -1) == '/') $master_php_ini_path = substr($master_php_ini_path, 0, -1);
72695f 884                 $master_php_ini_path .= '/php.ini';
T 885             }
7fe908 886
MC 887             if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
c77103 888                 $php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
7fddfe 889             }
7fe908 890             $php_ini_content .= str_replace("\r", '', trim($data['new']['custom_php_ini']));
MC 891             $app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
7fddfe 892         } else {
T 893             $has_custom_php_ini = false;
c77103 894             if(is_file($custom_php_ini_dir.'/php.ini')) $app->system->unlink($custom_php_ini_dir.'/php.ini');
7fddfe 895         }
T 896
897
898         //* Create the vhost config file
46c683 899         $app->load('tpl');
ac933e 900
46c683 901         $tpl = new tpl();
fb3339 902         $tpl->newTemplate('vhost.conf.master');
ac933e 903
fb3339 904         $vhost_data = $data['new'];
a7bdf8 905         //unset($vhost_data['ip_address']);
6fb93d 906         $vhost_data['web_document_root'] = $data['new']['document_root'].'/' . $web_folder;
M 907         $vhost_data['web_document_root_www'] = $web_config['website_basedir'].'/'.$data['new']['domain'].'/' . $web_folder;
fb3339 908         $vhost_data['web_basedir'] = $web_config['website_basedir'];
J 909         $vhost_data['security_level'] = $web_config['security_level'];
910         $vhost_data['allow_override'] = ($data['new']['allow_override'] == '')?'All':$data['new']['allow_override'];
911         $vhost_data['php_open_basedir'] = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
912         $vhost_data['ssl_domain'] = $data['new']['ssl_domain'];
913         $vhost_data['has_custom_php_ini'] = $has_custom_php_ini;
914         $vhost_data['custom_php_ini_dir'] = escapeshellcmd($custom_php_ini_dir);
7fe908 915
02bf99 916         // Custom Apache directives
T 917         // Make sure we only have Unix linebreaks
918         $vhost_data['apache_directives'] = str_replace("\r\n", "\n", $vhost_data['apache_directives']);
919         $vhost_data['apache_directives'] = str_replace("\r", "\n", $vhost_data['apache_directives']);
018955 920         $trans = array('{DOCROOT}' => $vhost_data['web_document_root_www']);
FT 921         $vhost_data['apache_directives'] = strtr($vhost_data['apache_directives'], $trans);
ac933e 922
46c683 923         // Check if a SSL cert exists
fb3339 924         $ssl_dir = $data['new']['document_root'].'/ssl';
J 925         $domain = $data['new']['ssl_domain'];
926         $key_file = $ssl_dir.'/'.$domain.'.key';
927         $crt_file = $ssl_dir.'/'.$domain.'.crt';
928         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
ac933e 929
a7bdf8 930         /*
1a2310 931         if($domain!='' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
fb3339 932             $vhost_data['ssl_enabled'] = 1;
J 933             $app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
46c683 934         } else {
fb3339 935             $vhost_data['ssl_enabled'] = 0;
1a2310 936             $app->log('SSL Disabled. '.$domain,LOGLEVEL_DEBUG);
46c683 937         }
a7bdf8 938         */
ac933e 939
46c683 940         if(@is_file($bundle_file)) $vhost_data['has_bundle_cert'] = 1;
ac933e 941
6fb93d 942         //$vhost_data['document_root'] = $data['new']['document_root'].'/' . $web_folder;
7fe908 943
e64fbb 944         // Set SEO Redirect
bfcdef 945         if($data['new']['seo_redirect'] != ''){
e64fbb 946             $vhost_data['seo_redirect_enabled'] = 1;
bfcdef 947             $tmp_seo_redirects = $this->get_seo_redirects($data['new']);
T 948             if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
949                 foreach($tmp_seo_redirects as $key => $val){
950                     $vhost_data[$key] = $val;
951                 }
952             } else {
953                 $vhost_data['seo_redirect_enabled'] = 0;
e64fbb 954             }
F 955         } else {
956             $vhost_data['seo_redirect_enabled'] = 0;
957         }
7fe908 958
46c683 959         $tpl->setVar($vhost_data);
8133de 960         $tpl->setVar('apache_version', $app->system->getapacheversion());
ac933e 961
46c683 962         // Rewrite rules
T 963         $rewrite_rules = array();
02bf99 964         if($data['new']['redirect_type'] != '' && $data['new']['redirect_path'] != '') {
7fe908 965             if(substr($data['new']['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $data['new']['redirect_path'])) $data['new']['redirect_path'] .= '/';
MC 966             if(substr($data['new']['redirect_path'], 0, 8) == '[scheme]'){
967                 $rewrite_target = 'http'.substr($data['new']['redirect_path'], 8);
968                 $rewrite_target_ssl = 'https'.substr($data['new']['redirect_path'], 8);
45ee67 969             } else {
F 970                 $rewrite_target = $data['new']['redirect_path'];
971                 $rewrite_target_ssl = $data['new']['redirect_path'];
972             }
bc2c3e 973             /* Disabled path extension
fb3339 974             if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 975                 $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 976             }
bc2c3e 977             */
ac933e 978
fb3339 979             switch($data['new']['subdomain']) {
7fe908 980             case 'www':
MC 981                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
982                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
983                     'rewrite_target'  => $rewrite_target,
984                     'rewrite_target_ssl' => $rewrite_target_ssl,
985                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
986                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
987                 $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$data['new']['domain']),
988                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
989                     'rewrite_target'  => $rewrite_target,
990                     'rewrite_target_ssl' => $rewrite_target_ssl,
991                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
992                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
993                 break;
994             case '*':
995                 $rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($data['new']['domain']),
996                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
997                     'rewrite_target'  => $rewrite_target,
998                     'rewrite_target_ssl' => $rewrite_target_ssl,
999                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1000                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1001                 break;
1002             default:
1003                 $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($data['new']['domain']),
1004                     'rewrite_type'   => ($data['new']['redirect_type'] == 'no')?'':'['.$data['new']['redirect_type'].']',
1005                     'rewrite_target'  => $rewrite_target,
1006                     'rewrite_target_ssl' => $rewrite_target_ssl,
1007                     'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1008                     'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1009             }
46c683 1010         }
7fe908 1011
3501f9 1012         $server_alias = array();
7fe908 1013
3501f9 1014         // get autoalias
M 1015         $auto_alias = $web_config['website_autoalias'];
1016         if($auto_alias != '') {
1017             // get the client username
1018             $client = $app->db->queryOneRecord("SELECT `username` FROM `client` WHERE `client_id` = '" . intval($client_id) . "'");
1019             $aa_search = array('[client_id]', '[website_id]', '[client_username]', '[website_domain]');
1020             $aa_replace = array($client_id, $data['new']['domain_id'], $client['username'], $data['new']['domain']);
1021             $auto_alias = str_replace($aa_search, $aa_replace, $auto_alias);
1022             unset($client);
1023             unset($aa_search);
1024             unset($aa_replace);
cece69 1025             $server_alias[] .= $auto_alias.' ';
3501f9 1026         }
7fe908 1027
46c683 1028         // get alias domains (co-domains and subdomains)
6fb93d 1029         $aliases = $app->db->queryAllRecords('SELECT * FROM web_domain WHERE parent_domain_id = '.$data['new']['domain_id']." AND active = 'y' AND type != 'vhostsubdomain'");
bfcdef 1030         $alias_seo_redirects = array();
fb3339 1031         switch($data['new']['subdomain']) {
7fe908 1032         case 'www':
MC 1033             $server_alias[] .= 'www.'.$data['new']['domain'].' ';
1034             break;
1035         case '*':
1036             $server_alias[] .= '*.'.$data['new']['domain'].' ';
1037             break;
ac933e 1038         }
46c683 1039         if(is_array($aliases)) {
T 1040             foreach($aliases as $alias) {
fb3339 1041                 switch($alias['subdomain']) {
7fe908 1042                 case 'www':
MC 1043                     $server_alias[] .= 'www.'.$alias['domain'].' '.$alias['domain'].' ';
1044                     break;
1045                 case '*':
1046                     $server_alias[] .= '*.'.$alias['domain'].' '.$alias['domain'].' ';
1047                     break;
1048                 default:
1049                     $server_alias[] .= $alias['domain'].' ';
1050                     break;
ac933e 1051                 }
7fe908 1052                 $app->log('Add server alias: '.$alias['domain'], LOGLEVEL_DEBUG);
MC 1053
bfcdef 1054                 // Add SEO redirects for alias domains
T 1055                 if($alias['seo_redirect'] != '' && $data['new']['seo_redirect'] != '*_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_to_domain_tld' && ($alias['type'] == 'alias' || ($alias['type'] == 'subdomain' && $data['new']['seo_redirect'] != '*_domain_tld_to_www_domain_tld' && $data['new']['seo_redirect'] != '*_domain_tld_to_domain_tld'))){
1056                     $tmp_seo_redirects = $this->get_seo_redirects($alias, 'alias_');
1057                     if(is_array($tmp_seo_redirects) && !empty($tmp_seo_redirects)){
1058                         $alias_seo_redirects[] = $tmp_seo_redirects;
1059                     }
1060                 }
7fe908 1061
46c683 1062                 // Rewriting
02bf99 1063                 if($alias['redirect_type'] != '' && $alias['redirect_path'] != '') {
7fe908 1064                     if(substr($alias['redirect_path'], -1) != '/' && !preg_match('/^(https?|\[scheme\]):\/\//', $alias['redirect_path'])) $alias['redirect_path'] .= '/';
MC 1065                     if(substr($alias['redirect_path'], 0, 8) == '[scheme]'){
1066                         $rewrite_target = 'http'.substr($alias['redirect_path'], 8);
1067                         $rewrite_target_ssl = 'https'.substr($alias['redirect_path'], 8);
e64fbb 1068                     } else {
F 1069                         $rewrite_target = $alias['redirect_path'];
1070                         $rewrite_target_ssl = $alias['redirect_path'];
1071                     }
bc2c3e 1072                     /* Disabled the path extension
fb3339 1073                     if($data['new']['redirect_type'] == 'no' && substr($data['new']['redirect_path'],0,4) != 'http') {
J 1074                         $data['new']['redirect_path'] = $data['new']['document_root'].'/web'.realpath($data['new']['redirect_path']).'/';
8388ae 1075                     }
bc2c3e 1076                     */
7fe908 1077
fb3339 1078                     switch($alias['subdomain']) {
7fe908 1079                     case 'www':
MC 1080                         $rewrite_rules[] = array( 'rewrite_domain'  => '^'.$this->_rewrite_quote($alias['domain']),
1081                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1082                             'rewrite_target'  => $rewrite_target,
1083                             'rewrite_target_ssl' => $rewrite_target_ssl,
1084                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1085                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1086                         $rewrite_rules[] = array( 'rewrite_domain'  => '^' . $this->_rewrite_quote('www.'.$alias['domain']),
1087                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1088                             'rewrite_target'  => $rewrite_target,
1089                             'rewrite_target_ssl' => $rewrite_target_ssl,
1090                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1091                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1092                         break;
1093                     case '*':
1094                         $rewrite_rules[] = array( 'rewrite_domain'  => '(^|\.)'.$this->_rewrite_quote($alias['domain']),
1095                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1096                             'rewrite_target'  => $rewrite_target,
1097                             'rewrite_target_ssl' => $rewrite_target_ssl,
1098                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1099                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
1100                         break;
1101                     default:
1102                         if(substr($alias['domain'], 0, 2) === '*.') $domain_rule = '(^|\.)'.$this->_rewrite_quote(substr($alias['domain'], 2));
1103                         else $domain_rule = '^'.$this->_rewrite_quote($alias['domain']);
1104                         $rewrite_rules[] = array( 'rewrite_domain'  => $domain_rule,
1105                             'rewrite_type'   => ($alias['redirect_type'] == 'no')?'':'['.$alias['redirect_type'].']',
1106                             'rewrite_target'  => $rewrite_target,
1107                             'rewrite_target_ssl' => $rewrite_target_ssl,
1108                             'rewrite_is_url'    => ($this->_is_url($rewrite_target) ? 'y' : 'n'),
1109                             'rewrite_add_path' => (substr($rewrite_target, -1) == '/' ? 'y' : 'n'));
ac933e 1110                     }
46c683 1111                 }
T 1112             }
1113         }
ac933e 1114
47cca9 1115         //* If we have some alias records
T 1116         if(count($server_alias) > 0) {
1117             $server_alias_str = '';
1118             $n = 0;
ac933e 1119
47cca9 1120             // begin a new ServerAlias line after 30 alias domains
T 1121             foreach($server_alias as $tmp_alias) {
1122                 if($n % 30 == 0) $server_alias_str .= "\n    ServerAlias ";
1123                 $server_alias_str .= $tmp_alias;
1124             }
1125             unset($tmp_alias);
ac933e 1126
7fe908 1127             $tpl->setVar('alias', trim($server_alias_str));
47cca9 1128         } else {
7fe908 1129             $tpl->setVar('alias', '');
47cca9 1130         }
ac933e 1131
bfcdef 1132         if(count($rewrite_rules) > 0 || $vhost_data['seo_redirect_enabled'] > 0 || count($alias_seo_redirects) > 0) {
7fe908 1133             $tpl->setVar('rewrite_enabled', 1);
46c683 1134         } else {
7fe908 1135             $tpl->setVar('rewrite_enabled', 0);
bfcdef 1136         }
8ab3cd 1137
T 1138         //$tpl->setLoop('redirects',$rewrite_rules);
ac933e 1139
V 1140         /**
1141          * install fast-cgi starter script and add script aliasd config
46c683 1142          * first we create the script directory if not already created, then copy over the starter script
T 1143          * settings are copied over from the server ini config for now
1144          * TODO: Create form for fastcgi configs per site.
1145          */
ac933e 1146
7fe908 1147
fb3339 1148         if ($data['new']['php'] == 'fast-cgi') {
ac933e 1149
7fe908 1150             $fastcgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1151             $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
ac933e 1152
V 1153             if (!is_dir($fastcgi_starter_path)) {
c77103 1154                 $app->system->mkdirpath($fastcgi_starter_path);
fb3339 1155                 //exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
ac933e 1156
V 1157
7fe908 1158                 $app->log('Creating fastcgi starter script directory: '.$fastcgi_starter_path, LOGLEVEL_DEBUG);
46c683 1159             }
ac933e 1160
c77103 1161             //exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($fastcgi_starter_path));
7fe908 1162             $app->system->chown($fastcgi_starter_path, $data['new']['system_user']);
MC 1163             $app->system->chgrp($fastcgi_starter_path, $data['new']['system_group']);
1164
46c683 1165             $fcgi_tpl = new tpl();
fb3339 1166             $fcgi_tpl->newTemplate('php-fcgi-starter.master');
8133de 1167             $fcgi_tpl->setVar('apache_version', $app->system->getapacheversion());
7fe908 1168
62b385 1169             // Support for multiple PHP versions (FastCGI)
F 1170             if(trim($data['new']['fastcgi_php_version']) != ''){
1171                 $default_fastcgi_php = false;
7fe908 1172                 if(substr($custom_fastcgi_php_ini_dir, -1) != '/') $custom_fastcgi_php_ini_dir .= '/';
62b385 1173             } else {
F 1174                 $default_fastcgi_php = true;
1175             }
7fe908 1176
7fddfe 1177             if($has_custom_php_ini) {
7fe908 1178                 $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1179             } else {
62b385 1180                 if($default_fastcgi_php){
7fe908 1181                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
62b385 1182                 } else {
7fe908 1183                     $fcgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_fastcgi_php_ini_dir));
62b385 1184                 }
7fddfe 1185             }
7fe908 1186             $fcgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
MC 1187             $fcgi_tpl->setVar('php_fcgi_children', escapeshellcmd($fastcgi_config['fastcgi_children']));
1188             $fcgi_tpl->setVar('php_fcgi_max_requests', escapeshellcmd($fastcgi_config['fastcgi_max_requests']));
62b385 1189             if($default_fastcgi_php){
7fe908 1190                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($fastcgi_config['fastcgi_bin']));
62b385 1191             } else {
7fe908 1192                 $fcgi_tpl->setVar('php_fcgi_bin', escapeshellcmd($custom_fastcgi_php_executable));
62b385 1193             }
7fe908 1194             $fcgi_tpl->setVar('security_level', intval($web_config['security_level']));
f63910 1195             $fcgi_tpl->setVar('domain', escapeshellcmd($data['new']['domain']));
ac933e 1196
fb3339 1197             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ff7075 1198             $fcgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
ac933e 1199
6fb93d 1200             $fcgi_starter_script = escapeshellcmd($fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
7fe908 1201             $app->system->file_put_contents($fcgi_starter_script, $fcgi_tpl->grab());
46c683 1202             unset($fcgi_tpl);
ac933e 1203
7fe908 1204             $app->log('Creating fastcgi starter script: '.$fcgi_starter_script, LOGLEVEL_DEBUG);
ac933e 1205
7fe908 1206             $app->system->chmod($fcgi_starter_script, 0755);
MC 1207             $app->system->chown($fcgi_starter_script, $data['new']['system_user']);
1208             $app->system->chgrp($fcgi_starter_script, $data['new']['system_group']);
1209
1210             $tpl->setVar('fastcgi_alias', $fastcgi_config['fastcgi_alias']);
1211             $tpl->setVar('fastcgi_starter_path', $fastcgi_starter_path);
1212             $tpl->setVar('fastcgi_starter_script', $fastcgi_config['fastcgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
1213             $tpl->setVar('fastcgi_config_syntax', $fastcgi_config['fastcgi_config_syntax']);
1214             $tpl->setVar('fastcgi_max_requests', $fastcgi_config['fastcgi_max_requests']);
ac933e 1215
62e4b3 1216         } else {
F 1217             //remove the php fastgi starter script if available
b5b862 1218             $fastcgi_starter_script = $fastcgi_config['fastcgi_starter_script'].($data['old']['type'] == 'vhostsubdomain' ? '_web' . $data['old']['domain_id'] : '');
62e4b3 1219             if ($data['old']['php'] == 'fast-cgi') {
7fe908 1220                 $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
MC 1221                 $fastcgi_starter_path = str_replace('[client_id]', $client_id, $fastcgi_starter_path);
1222                 if($data['old']['type'] == 'vhost') {
b5b862 1223                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
TB 1224                     if (is_dir($fastcgi_starter_path)) @rmdir($fastcgi_starter_path);
7fe908 1225                 } else {
b5b862 1226                     if(is_file($fastcgi_starter_script)) @unlink($fastcgi_starter_script);
7fe908 1227                 }
62e4b3 1228             }
46c683 1229         }
7fe908 1230
MC 1231
1232
274362 1233         /**
7fe908 1234          * PHP-FPM
MC 1235          */
274362 1236         // Support for multiple PHP versions
62e4b3 1237         if($data['new']['php'] == 'php-fpm'){
F 1238             if(trim($data['new']['fastcgi_php_version']) != ''){
1239                 $default_php_fpm = false;
1240                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
7fe908 1241                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1242             } else {
F 1243                 $default_php_fpm = true;
1244             }
274362 1245         } else {
62e4b3 1246             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 1247                 $default_php_fpm = false;
1248                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 1249                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 1250             } else {
F 1251                 $default_php_fpm = true;
1252             }
274362 1253         }
7fe908 1254
274362 1255         if($default_php_fpm){
F 1256             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
1257         } else {
1258             $pool_dir = $custom_php_fpm_pool_dir;
1259         }
7fe908 1260         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 1261         $pool_name = 'web'.$data['new']['domain_id'];
F 1262         $socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
7fe908 1263         if(substr($socket_dir, -1) != '/') $socket_dir .= '/';
MC 1264
274362 1265         if($data['new']['php_fpm_use_socket'] == 'y'){
F 1266             $use_tcp = 0;
1267             $use_socket = 1;
1268         } else {
1269             $use_tcp = 1;
1270             $use_socket = 0;
1271         }
1272         $tpl->setVar('use_tcp', $use_tcp);
1273         $tpl->setVar('use_socket', $use_socket);
1274         $fpm_socket = $socket_dir.$pool_name.'.sock';
1275         $tpl->setVar('fpm_socket', $fpm_socket);
1276         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
ac933e 1277
46c683 1278         /**
T 1279          * install cgi starter script and add script alias to config.
1280          * This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
1281          * first we create the script directory if not already created, then copy over the starter script.
1282          * TODO: we have to fetch the data from the server-settings.
1283          */
fb3339 1284         if ($data['new']['php'] == 'cgi') {
J 1285             //$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
46c683 1286
fb3339 1287             $cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
6fb93d 1288             $cgi_config['cgi_starter_script'] = 'php-cgi-starter'.($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : '');
fb3339 1289             $cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
46c683 1290
7fe908 1291             $cgi_starter_path = str_replace('[system_user]', $data['new']['system_user'], $cgi_config['cgi_starter_path']);
MC 1292             $cgi_starter_path = str_replace('[client_id]', $client_id, $cgi_starter_path);
46c683 1293
ac933e 1294             if (!is_dir($cgi_starter_path)) {
c77103 1295                 $app->system->mkdirpath($cgi_starter_path);
7fe908 1296                 $app->system->chown($cgi_starter_path, $data['new']['system_user']);
MC 1297                 $app->system->chgrp($cgi_starter_path, $data['new']['system_group']);
1298                 $app->system->chmod($cgi_starter_path, 0755);
46c683 1299
7fe908 1300                 $app->log('Creating cgi starter script directory: '.$cgi_starter_path, LOGLEVEL_DEBUG);
46c683 1301             }
T 1302
1303             $cgi_tpl = new tpl();
fb3339 1304             $cgi_tpl->newTemplate('php-cgi-starter.master');
8133de 1305             $cgi_tpl->setVar('apache_version', $app->system->getapacheversion());
46c683 1306
fb3339 1307             // This works because PHP "rewrites" a symlink to the physical path
J 1308             $php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
ac933e 1309             $cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
fb3339 1310             $cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
ac933e 1311
46c683 1312             // This will NOT work!
fb3339 1313             //$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
7fe908 1314             $cgi_tpl->setVar('php_cgi_bin', $cgi_config['cgi_bin']);
MC 1315             $cgi_tpl->setVar('security_level', $web_config['security_level']);
1316
1317             $cgi_tpl->setVar('has_custom_php_ini', $has_custom_php_ini);
7fddfe 1318             if($has_custom_php_ini) {
7fe908 1319                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($custom_php_ini_dir));
7fddfe 1320             } else {
7fe908 1321                 $cgi_tpl->setVar('php_ini_path', escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
7fddfe 1322             }
46c683 1323
6fb93d 1324             $cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
7fe908 1325             $app->system->file_put_contents($cgi_starter_script, $cgi_tpl->grab());
46c683 1326             unset($cgi_tpl);
T 1327
7fe908 1328             $app->log('Creating cgi starter script: '.$cgi_starter_script, LOGLEVEL_DEBUG);
46c683 1329
T 1330
7fe908 1331             $app->system->chmod($cgi_starter_script, 0755);
MC 1332             $app->system->chown($cgi_starter_script, $data['new']['system_user']);
1333             $app->system->chgrp($cgi_starter_script, $data['new']['system_group']);
46c683 1334
7fe908 1335             $tpl->setVar('cgi_starter_path', $cgi_starter_path);
MC 1336             $tpl->setVar('cgi_starter_script', $cgi_config['cgi_starter_script'].($data['new']['type'] == 'vhostsubdomain' ? '_web' . $data['new']['domain_id'] : ''));
46c683 1337
T 1338         }
1339
fb3339 1340         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
7ed741 1341         //* Make a backup copy of vhost file
7fe908 1342         if(file_exists($vhost_file)) $app->system->copy($vhost_file, $vhost_file.'~');
MC 1343
a7bdf8 1344         //* create empty vhost array
T 1345         $vhosts = array();
7fe908 1346
526b99 1347         //* Add vhost for ipv4 IP
T 1348         $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
1349         if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1350         if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1351         $vhosts[] = $tmp_vhost_arr;
1352         unset($tmp_vhost_arr);
7fe908 1353
a7bdf8 1354         //* Add vhost for ipv4 IP with SSL
481c00 1355         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1356         $domain = $data['new']['ssl_domain'];
1357         $key_file = $ssl_dir.'/'.$domain.'.key';
1358         $crt_file = $ssl_dir.'/'.$domain.'.crt';
7fe908 1359
a7bdf8 1360         if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1361             $tmp_vhost_arr = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
T 1362             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1363             $ipv4_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1364             if(is_array($ipv4_ssl_alias_seo_redirects) && !empty($ipv4_ssl_alias_seo_redirects)){
1365                 for($i=0;$i<count($ipv4_ssl_alias_seo_redirects);$i++){
1366                     $ipv4_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1367                 }
1368             }
1369             if(count($ipv4_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv4_ssl_alias_seo_redirects);
526b99 1370             $vhosts[] = $tmp_vhost_arr;
cc6568 1371             unset($tmp_vhost_arr, $ipv4_ssl_alias_seo_redirects);
7fe908 1372             $app->log('Enable SSL for: '.$domain, LOGLEVEL_DEBUG);
146783 1373         }
MC 1374
7fe908 1375         //* Add vhost for IPv6 IP
MC 1376         if($data['new']['ipv6_address'] != '') {
1377             if ($conf['serverconfig']['web']['vhost_rewrite_v6'] == 'y') {
1378                 if (isset($conf['serverconfig']['server']['v6_prefix']) && $conf['serverconfig']['server']['v6_prefix'] <> '') {
1379                     $explode_v6prefix=explode(':', $conf['serverconfig']['server']['v6_prefix']);
1380                     $explode_v6=explode(':', $data['new']['ipv6_address']);
1381
1382                     for ( $i = 0; $i <= count($explode_v6prefix)-3; $i++ ) {
1383                         $explode_v6[$i] = $explode_v6prefix[$i];
1384                     }
1385                     $data['new']['ipv6_address'] = implode(':', $explode_v6);
146783 1386                 }
MC 1387             }
7fe908 1388
526b99 1389             $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
T 1390             if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
1391             if(count($alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $alias_seo_redirects);
1392             $vhosts[] = $tmp_vhost_arr;
1393             unset($tmp_vhost_arr);
7fe908 1394
a7bdf8 1395             //* Add vhost for ipv6 IP with SSL
T 1396             if($data['new']['ssl_domain'] != '' && $data['new']['ssl'] == 'y' && @is_file($crt_file) && @is_file($key_file) && (@filesize($crt_file)>0)  && (@filesize($key_file)>0)) {
526b99 1397                 $tmp_vhost_arr = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
T 1398                 if(count($rewrite_rules) > 0)  $tmp_vhost_arr = $tmp_vhost_arr + array('redirects' => $rewrite_rules);
cc6568 1399                 $ipv6_ssl_alias_seo_redirects = $alias_seo_redirects;
H 1400                 if(is_array($ipv6_ssl_alias_seo_redirects) && !empty($ipv6_ssl_alias_seo_redirects)){
1401                     for($i=0;$i<count($ipv6_ssl_alias_seo_redirects);$i++){
1402                         $ipv6_ssl_alias_seo_redirects[$i]['ssl_enabled'] = 1;
1403                     }
1404                 }
1405                 if(count($ipv6_ssl_alias_seo_redirects) > 0) $tmp_vhost_arr = $tmp_vhost_arr + array('alias_seo_redirects' => $ipv6_ssl_alias_seo_redirects);
526b99 1406                 $vhosts[] = $tmp_vhost_arr;
cc6568 1407                 unset($tmp_vhost_arr, $ipv6_ssl_alias_seo_redirects);
7fe908 1408                 $app->log('Enable SSL for IPv6: '.$domain, LOGLEVEL_DEBUG);
a7bdf8 1409             }
T 1410         }
7fe908 1411
a7bdf8 1412         //* Set the vhost loop
7fe908 1413         $tpl->setLoop('vhosts', $vhosts);
MC 1414
7ed741 1415         //* Write vhost file
7fe908 1416         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1417         $app->log('Writing the vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1418         unset($tpl);
ac933e 1419
V 1420         /*
1421          * maybe we have some webdav - user. If so, add them...
1422         */
fb3339 1423         $this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
ac933e 1424
c6a89c 1425         //* Set the symlink to enable the vhost
T 1426         //* First we check if there is a old type of symlink and remove it
fb3339 1427         $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
c77103 1428         if(is_link($vhost_symlink)) $app->system->unlink($vhost_symlink);
7fe908 1429
c6a89c 1430         //* Remove old or changed symlinks
T 1431         if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
1432             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1433             if(is_link($vhost_symlink)) {
c77103 1434                 $app->system->unlink($vhost_symlink);
7fe908 1435                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1436             }
T 1437             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1438             if(is_link($vhost_symlink)) {
c77103 1439                 $app->system->unlink($vhost_symlink);
7fe908 1440                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1441             }
T 1442         }
7fe908 1443
c6a89c 1444         //* New symlink
T 1445         if($data['new']['subdomain'] == '*') {
1446             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
1447         } else {
1448             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
1449         }
fb3339 1450         if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
7fe908 1451             symlink($vhost_file, $vhost_symlink);
MC 1452             $app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
46c683 1453         }
ac933e 1454
46c683 1455         // remove old symlink and vhost file, if domain name of the site has changed
fb3339 1456         if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
c6a89c 1457             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
T 1458             if(is_link($vhost_symlink)) {
c77103 1459                 $app->system->unlink($vhost_symlink);
7fe908 1460                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1461             }
T 1462             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1463             if(is_link($vhost_symlink)) {
c77103 1464                 $app->system->unlink($vhost_symlink);
7fe908 1465                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
c6a89c 1466             }
8cf78b 1467             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1468             if(is_link($vhost_symlink)) {
c77103 1469                 $app->system->unlink($vhost_symlink);
7fe908 1470                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8cf78b 1471             }
fb3339 1472             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
c77103 1473             $app->system->unlink($vhost_file);
7fe908 1474             $app->log('Removing file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1475         }
ac933e 1476
46c683 1477         //* Create .htaccess and .htpasswd file for website statistics
cc6568 1478         //if(!is_file($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
H 1479         if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/stats')) $app->system->mkdir($data['new']['document_root'].'/' . $web_folder . '/stats');
1480         $ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/web/stats/.htpasswd_stats\nrequire valid-user";
7fe908 1481         $app->system->file_put_contents($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', $ht_file);
746bf0 1482         $app->system->chmod($data['new']['document_root'].'/' . $web_folder . '/stats/.htaccess', 0755);
cc6568 1483         unset($ht_file);
H 1484         //}
ac933e 1485
bfcdef 1486         if(!is_file($data['new']['document_root'].'/web/stats/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
fb3339 1487             if(trim($data['new']['stats_password']) != '') {
J 1488                 $htp_file = 'admin:'.trim($data['new']['stats_password']);
7fe908 1489                 $app->system->web_folder_protection($data['new']['document_root'], false);
MC 1490                 $app->system->file_put_contents($data['new']['document_root'].'/web/stats/.htpasswd_stats', $htp_file);
1491                 $app->system->web_folder_protection($data['new']['document_root'], true);
746bf0 1492                 $app->system->chmod($data['new']['document_root'].'/web/stats/.htpasswd_stats', 0755);
46c683 1493                 unset($htp_file);
T 1494             }
1495         }
7fe908 1496
58c210 1497         //* Create awstats configuration
6fb93d 1498         if($data['new']['stats_type'] == 'awstats' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain')) {
7fe908 1499             $this->awstats_update($data, $web_config);
58c210 1500         }
7fe908 1501
MC 1502         $this->php_fpm_pool_update($data, $web_config, $pool_dir, $pool_name, $socket_dir);
1503
7ed741 1504         if($web_config['check_apache_config'] == 'y') {
T 1505             //* Test if apache starts with the new configuration file
7fe908 1506             $apache_online_status_before_restart = $this->_checkTcp('localhost', 80);
MC 1507             $app->log('Apache status is: '.($apache_online_status_before_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
ac933e 1508
7fe908 1509             $retval = $app->services->restartService('httpd', 'restart'); // $retval['retval'] is 0 on success and > 0 on failure
MC 1510             $app->log('Apache restart return value is: '.$retval['retval'], LOGLEVEL_DEBUG);
1511
9f56bd 1512             // wait a few seconds, before we test the apache status again
bfcdef 1513             $apache_online_status_after_restart = false;
9f56bd 1514             sleep(2);
bfcdef 1515             for($i = 0; $i < 5; $i++) {
7fe908 1516                 $apache_online_status_after_restart = $this->_checkTcp('localhost', 80);
bfcdef 1517                 if($apache_online_status_after_restart) break;
T 1518                 sleep(1);
1519             }
7ed741 1520             //* Check if apache restarted successfully if it was online before
7fe908 1521             $app->log('Apache online status after restart is: '.($apache_online_status_after_restart === true? 'running' : 'down'), LOGLEVEL_DEBUG);
615a0a 1522             if($apache_online_status_before_restart && !$apache_online_status_after_restart || $retval['retval'] > 0) {
7fe908 1523                 $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].'. Reverting the configuration. Saved non-working config as '.$vhost_file.'.err', LOGLEVEL_WARN);
615a0a 1524                 if(is_array($retval['output']) && !empty($retval['output'])){
7fe908 1525                     $app->log('Reason for Apache restart failure: '.implode("\n", $retval['output']), LOGLEVEL_WARN);
7b47c0 1526                     $app->dbmaster->datalogError(implode("\n", $retval['output']));
615a0a 1527                 } else {
T 1528                     // if no output is given, check again
1529                     $webserver_binary = '';
7b47c0 1530                     exec('which apache2ctl', $webserver_check_output, $webserver_check_retval);
615a0a 1531                     if($webserver_check_retval == 0){
7b47c0 1532                         $webserver_binary = 'apache2ctl';
615a0a 1533                     } else {
T 1534                         unset($webserver_check_output, $webserver_check_retval);
7b47c0 1535                         exec('which apache2', $webserver_check_output, $webserver_check_retval);
615a0a 1536                         if($webserver_check_retval == 0){
7b47c0 1537                             $webserver_binary = 'apache2';
615a0a 1538                         } else {
T 1539                             unset($webserver_check_output, $webserver_check_retval);
7b47c0 1540                             exec('which httpd2', $webserver_check_output, $webserver_check_retval);
615a0a 1541                             if($webserver_check_retval == 0){
7b47c0 1542                                 $webserver_binary = 'httpd2';
615a0a 1543                             } else {
T 1544                                 unset($webserver_check_output, $webserver_check_retval);
7b47c0 1545                                 exec('which httpd', $webserver_check_output, $webserver_check_retval);
615a0a 1546                                 if($webserver_check_retval == 0){
7b47c0 1547                                     $webserver_binary = 'httpd';
T 1548                                 } else {
1549                                     unset($webserver_check_output, $webserver_check_retval);
1550                                     exec('which apache', $webserver_check_output, $webserver_check_retval);
1551                                     if($webserver_check_retval == 0){
1552                                         $webserver_binary = 'apache';
1553                                     }
615a0a 1554                                 }
T 1555                             }
1556                         }
1557                     }
1558                     if($webserver_binary != ''){
1559                         exec($webserver_binary.' -t 2>&1', $tmp_output, $tmp_retval);
7b47c0 1560                         if($tmp_retval > 0 && is_array($tmp_output) && !empty($tmp_output)){
7fe908 1561                             $app->log('Reason for Apache restart failure: '.implode("\n", $tmp_output), LOGLEVEL_WARN);
7b47c0 1562                             $app->dbmaster->datalogError(implode("\n", $tmp_output));
T 1563                         }
615a0a 1564                         unset($tmp_output, $tmp_retval);
T 1565                     }
1566                 }
7fe908 1567                 $app->system->copy($vhost_file, $vhost_file.'.err');
8cf78b 1568                 if(is_file($vhost_file.'~')) {
T 1569                     //* Copy back the last backup file
7fe908 1570                     $app->system->copy($vhost_file.'~', $vhost_file);
8cf78b 1571                 } else {
T 1572                     //* There is no backup file, so we create a empty vhost file with a warning message inside
7fe908 1573                     $app->system->file_put_contents($vhost_file, "# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
8cf78b 1574                 }
481c00 1575                 if($this->ssl_certificate_changed === true) {
T 1576
1577                     $ssl_dir = $data['new']['document_root'].'/ssl';
1578                     $domain = $data['new']['ssl_domain'];
1579                     $key_file = $ssl_dir.'/'.$domain.'.key.org';
1580                     $key_file2 = $ssl_dir.'/'.$domain.'.key';
1581                     $csr_file = $ssl_dir.'/'.$domain.'.csr';
1582                     $crt_file = $ssl_dir.'/'.$domain.'.crt';
1583                     $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1584
481c00 1585                     //* Backup the files that might have caused the error
43b345 1586                     if(is_file($key_file)){
7fe908 1587                         $app->system->copy($key_file, $key_file.'.err');
MC 1588                         $app->system->chmod($key_file.'.err', 0400);
43b345 1589                     }
T 1590                     if(is_file($key_file2)){
7fe908 1591                         $app->system->copy($key_file2, $key_file2.'.err');
MC 1592                         $app->system->chmod($key_file2.'.err', 0400);
43b345 1593                     }
7fe908 1594                     if(is_file($csr_file)) $app->system->copy($csr_file, $csr_file.'.err');
MC 1595                     if(is_file($crt_file)) $app->system->copy($crt_file, $crt_file.'.err');
1596                     if(is_file($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'.err');
1597
481c00 1598                     //* Restore the ~ backup files
7fe908 1599                     if(is_file($key_file.'~')) $app->system->copy($key_file.'~', $key_file);
MC 1600                     if(is_file($key_file2.'~')) $app->system->copy($key_file2.'~', $key_file2);
1601                     if(is_file($crt_file.'~')) $app->system->copy($crt_file.'~', $crt_file);
1602                     if(is_file($csr_file.'~')) $app->system->copy($csr_file.'~', $csr_file);
1603                     if(is_file($bundle_file.'~')) $app->system->copy($bundle_file.'~', $bundle_file);
1604
1605                     $app->log('Apache did not restart after the configuration change for website '.$data['new']['domain'].' Reverting the SSL configuration. Saved non-working SSL files with .err extension.', LOGLEVEL_WARN);
481c00 1606                 }
7fe908 1607
MC 1608                 $app->services->restartService('httpd', 'restart');
7ed741 1609             }
c82dc7 1610         } else {
7ed741 1611             //* We do not check the apache config after changes (is faster)
T 1612             if($apache_chrooted) {
7fe908 1613                 $app->services->restartServiceDelayed('httpd', 'restart');
7ed741 1614             } else {
T 1615                 // request a httpd reload when all records have been processed
7fe908 1616                 $app->services->restartServiceDelayed('httpd', 'reload');
7ed741 1617             }
c82dc7 1618         }
7fe908 1619
MC 1620         //* The vhost is written and apache has been restarted, so we
481c00 1621         // can reset the ssl changed var to false and cleanup some files
T 1622         $this->ssl_certificate_changed = false;
7fe908 1623
481c00 1624         $ssl_dir = $data['new']['document_root'].'/ssl';
T 1625         $domain = $data['new']['ssl_domain'];
1626         $key_file = $ssl_dir.'/'.$domain.'.key.org';
1627         $key_file2 = $ssl_dir.'/'.$domain.'.key';
1628         $csr_file = $ssl_dir.'/'.$domain.'.csr';
1629         $crt_file = $ssl_dir.'/'.$domain.'.crt';
1630         $bundle_file = $ssl_dir.'/'.$domain.'.bundle';
7fe908 1631
c77103 1632         if(@is_file($key_file.'~')) $app->system->unlink($key_file.'~');
T 1633         if(@is_file($key2_file.'~')) $app->system->unlink($key2_file.'~');
1634         if(@is_file($crt_file.'~')) $app->system->unlink($crt_file.'~');
1635         if(@is_file($csr_file.'~')) $app->system->unlink($csr_file.'~');
1636         if(@is_file($bundle_file.'~')) $app->system->unlink($bundle_file.'~');
7fe908 1637
7ed741 1638         // Remove the backup copy of the config file.
c77103 1639         if(@is_file($vhost_file.'~')) $app->system->unlink($vhost_file.'~');
ac933e 1640
da1a7c 1641         //* Unset action to clean it for next processed vhost.
T 1642         $this->action = '';
46c683 1643     }
ac933e 1644
7fe908 1645     function delete($event_name, $data) {
46c683 1646         global $app, $conf;
ac933e 1647
46c683 1648         // load the server configuration options
fb3339 1649         $app->uses('getconf');
c09f04 1650         $app->uses('system');
fb3339 1651         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
cc6568 1652         $fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
7fe908 1653
MC 1654         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') $app->system->web_folder_protection($data['old']['document_root'], false);
ac933e 1655
2bbc4c 1656         //* Check if this is a chrooted setup
4b72c5 1657         if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2bbc4c 1658             $apache_chrooted = true;
T 1659         } else {
1660             $apache_chrooted = false;
1661         }
7fe908 1662
fea5e7 1663         //* Remove the mounts
T 1664         $log_folder = 'log';
7fe908 1665         $web_folder = '';
MC 1666         if($data['old']['type'] == 'vhostsubdomain') {
1667             $tmp = $app->db->queryOneRecord('SELECT `domain`,`document_root` FROM web_domain WHERE domain_id = '.intval($data['old']['parent_domain_id']));
526b99 1668             if($tmp['domain'] != ''){
T 1669                 $subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
1670             } else {
1671                 // get log folder from /etc/fstab
1672                 /*
1673                 $bind_mounts = $app->system->file_get_contents('/etc/fstab');
1674                 $bind_mount_lines = explode("\n", $bind_mounts);
1675                 if(is_array($bind_mount_lines) && !empty($bind_mount_lines)){
1676                     foreach($bind_mount_lines as $bind_mount_line){
1677                         $bind_mount_line = preg_replace('/\s+/', ' ', $bind_mount_line);
1678                         $bind_mount_parts = explode(' ', $bind_mount_line);
1679                         if(is_array($bind_mount_parts) && !empty($bind_mount_parts)){
1680                             if($bind_mount_parts[0] == '/var/log/ispconfig/httpd/'.$data['old']['domain'] && $bind_mount_parts[2] == 'none' && strpos($bind_mount_parts[3], 'bind') !== false){
1681                                 $subdomain_host = str_replace($data['old']['document_root'].'/log/', '', $bind_mount_parts[1]);
1682                             }
1683                         }
1684                     }
1685                 }
1686                 */
1687                 // we are deleting the parent domain, so we can delete everything in the log directory
1688                 $subdomain_hosts = array();
7fe908 1689                 $files = array_diff(scandir($data['old']['document_root'].'/'.$log_folder), array('.', '..'));
526b99 1690                 if(is_array($files) && !empty($files)){
T 1691                     foreach($files as $file){
1692                         if(is_dir($data['old']['document_root'].'/'.$log_folder.'/'.$file)){
1693                             $subdomain_hosts[] = $file;
1694                         }
1695                     }
1696                 }
1697             }
7fe908 1698             if(is_array($subdomain_hosts) && !empty($subdomain_hosts)){
526b99 1699                 $log_folders = array();
T 1700                 foreach($subdomain_hosts as $subdomain_host){
1701                     $log_folders[] = $log_folder.'/'.$subdomain_host;
1702                 }
1703             } else {
1704                 if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
1705                 $log_folder .= '/' . $subdomain_host;
1706             }
1707             $web_folder = $data['old']['web_folder'];
7fe908 1708             unset($tmp);
526b99 1709             unset($subdomain_hosts);
3cde19 1710         }
7fe908 1711
526b99 1712         if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain'){
T 1713             if(is_array($log_folders) && !empty($log_folders)){
1714                 foreach($log_folders as $log_folder){
cc6568 1715                     //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1716                     exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1717                 }
T 1718             } else {
cc6568 1719                 //if($app->system->is_mounted($data['old']['document_root'].'/'.$log_folder)) exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder));
H 1720                 exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$log_folder).' 2>/dev/null');
526b99 1721             }
T 1722         }
7fe908 1723
fea5e7 1724         //* remove mountpoint from fstab
526b99 1725         if(is_array($log_folders) && !empty($log_folders)){
T 1726             foreach($log_folders as $log_folder){
1727                 $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1728                 $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1729             }
T 1730         } else {
1731             $fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$log_folder.'    none    bind';
7fe908 1732             $app->system->removeLine('/etc/fstab', $fstab_line);
526b99 1733         }
T 1734         unset($log_folders);
ac933e 1735
6fb93d 1736         if($data['old']['type'] != 'vhost' && $data['old']['type'] != 'vhostsubdomain' && $data['old']['parent_domain_id'] > 0) {
46c683 1737             //* This is a alias domain or subdomain, so we have to update the website instead
fb3339 1738             $parent_domain_id = intval($data['old']['parent_domain_id']);
J 1739             $tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
1740             $data['new'] = $tmp;
1741             $data['old'] = $tmp;
46c683 1742             $this->action = 'update';
T 1743             // just run the update function
7fe908 1744             $this->update($event_name, $data);
ac933e 1745
46c683 1746         } else {
T 1747             //* This is a website
1748             // Deleting the vhost file, symlink and the data directory
fb3339 1749             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
7fe908 1750
8ab3cd 1751             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
T 1752             if(is_link($vhost_symlink)){
c77103 1753                 $app->system->unlink($vhost_symlink);
7fe908 1754                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1755             }
T 1756             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
1757             if(is_link($vhost_symlink)){
c77103 1758                 $app->system->unlink($vhost_symlink);
7fe908 1759                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1760             }
T 1761             $vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
1762             if(is_link($vhost_symlink)){
c77103 1763                 $app->system->unlink($vhost_symlink);
7fe908 1764                 $app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file, LOGLEVEL_DEBUG);
8ab3cd 1765             }
7fe908 1766
c77103 1767             $app->system->unlink($vhost_file);
7fe908 1768             $app->log('Removing vhost file: '.$vhost_file, LOGLEVEL_DEBUG);
ac933e 1769
7fe908 1770             if($data['old']['type'] == 'vhost' || $data['old']['type'] == 'vhostsubdomain') {
MC 1771                 $docroot = escapeshellcmd($data['old']['document_root']);
1772                 if($docroot != '' && !stristr($docroot, '..')) {
1773                     if($data['old']['type'] == 'vhost') {
1774                         // this is a vhost - we delete everything in here.
1775                         exec('rm -rf '.$docroot);
1776                     } elseif(!stristr($data['old']['web_folder'], '..')) {
1777                         // this is a vhost subdomain
1778                         // IMPORTANT: do some folder checks before we delete this!
1779                         $do_delete = true;
1780                         $delete_folder = preg_replace('/[\/]{2,}/', '/', $web_folder); // replace / occuring multiple times
1781                         if(substr($delete_folder, 0, 1) === '/') $delete_folder = substr($delete_folder, 1);
1782                         if(substr($delete_folder, -1) === '/') $delete_folder = substr($delete_folder, 0, -1);
46c683 1783
7fe908 1784                         $path_elements = explode('/', $delete_folder);
46c683 1785
7fe908 1786                         if($path_elements[0] == 'web' || $path_elements[0] === '') {
MC 1787                             // paths beginning with /web should NEVER EVER be deleted, empty paths should NEVER occur - but for safety reasons we check it here!
1788                             // we use strict check as otherwise directories named '0' may not be deleted
1789                             $do_delete = false;
1790                         } else {
1791                             // read all vhost subdomains with same parent domain
1792                             $used_paths = array();
1793                             $tmp = $app->db->queryAllRecords("SELECT `web_folder` FROM web_domain WHERE type = 'vhostsubdomain' AND parent_domain_id = ".intval($data['old']['parent_domain_id'])." AND domain_id != ".intval($data['old']['domain_id']));
1794                             foreach($tmp as $tmprec) {
1795                                 // we normalize the folder entries because we need to compare them
1796                                 $tmp_folder = preg_replace('/[\/]{2,}/', '/', $tmprec['web_folder']); // replace / occuring multiple times
1797                                 if(substr($tmp_folder, 0, 1) === '/') $tmp_folder = substr($tmp_folder, 1);
1798                                 if(substr($tmp_folder, -1) === '/') $tmp_folder = substr($tmp_folder, 0, -1);
ac933e 1799
7fe908 1800                                 // add this path and it's parent paths to used_paths array
MC 1801                                 while(strpos($tmp_folder, '/') !== false) {
1802                                     if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1803                                     $tmp_folder = substr($tmp_folder, 0, strrpos($tmp_folder, '/'));
1804                                 }
1805                                 if(in_array($tmp_folder, $used_paths) == false) $used_paths[] = $tmp_folder;
1806                             }
1807                             unset($tmp);
1808
1809                             // loop and check if the path is still used and stop at first used one
1810                             // set do_delete to false so nothing gets deleted if the web_folder itself is still used
1811                             $do_delete = false;
1812                             while(count($path_elements) > 0) {
1813                                 $tmp_folder = implode('/', $path_elements);
1814                                 if(in_array($tmp_folder, $used_paths) == true) break;
1815
1816                                 // this path is not used - set it as path to delete, strip the last element from the array and set do_delete to true
1817                                 $delete_folder = $tmp_folder;
1818                                 $do_delete = true;
1819                                 array_pop($path_elements);
1820                             }
1821                             unset($tmp_folder);
1822                             unset($used_paths);
1823                         }
1824
1825                         if($do_delete === true && $delete_folder !== '') exec('rm -rf '.$docroot.'/'.$delete_folder);
1826
1827                         unset($delete_folder);
1828                         unset($path_elements);
1829                     }
1830                 }
1831
1832                 //remove the php fastgi starter script if available
1833                 if ($data['old']['php'] == 'fast-cgi') {
1834                     $fastcgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $fastcgi_config['fastcgi_starter_path']);
1835                     if($data['old']['type'] == 'vhost') {
1836                         if (is_dir($fastcgi_starter_path)) {
1837                             exec('rm -rf '.$fastcgi_starter_path);
1838                         }
1839                     } else {
1840                         $fcgi_starter_script = $fastcgi_starter_path.$fastcgi_config['fastcgi_starter_script'].'_web'.$data['old']['domain_id'];
1841                         if (file_exists($fcgi_starter_script)) {
1842                             exec('rm -f '.$fcgi_starter_script);
1843                         }
1844                     }
1845                 }
1846
1847                 // remove PHP-FPM pool
1848                 if ($data['old']['php'] == 'php-fpm') {
1849                     $this->php_fpm_pool_delete($data, $web_config);
1850                 }
1851
1852                 //remove the php cgi starter script if available
1853                 if ($data['old']['php'] == 'cgi') {
1854                     // TODO: fetch the date from the server-settings
1855                     $web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
1856
1857                     $cgi_starter_path = str_replace('[system_user]', $data['old']['system_user'], $web_config['cgi_starter_path']);
1858                     if($data['old']['type'] == 'vhost') {
1859                         if (is_dir($cgi_starter_path)) {
1860                             exec('rm -rf '.$cgi_starter_path);
1861                         }
1862                     } else {
1863                         $cgi_starter_script = $cgi_starter_path.'php-cgi-starter_web'.$data['old']['domain_id'];
1864                         if (file_exists($cgi_starter_script)) {
1865                             exec('rm -f '.$cgi_starter_script);
1866                         }
1867                     }
1868                 }
1869
1870                 $app->log('Removing website: '.$docroot, LOGLEVEL_DEBUG);
1871
1872                 // Delete the symlinks for the sites
1873                 $client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
1874                 $client_id = intval($client['client_id']);
1875                 unset($client);
1876                 $tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
1877                 if(is_array($tmp_symlinks_array)) {
1878                     foreach($tmp_symlinks_array as $tmp_symlink) {
1879                         $tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
1880                         $tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
1881                         // Remove trailing slash
1882                         if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
1883                         // delete the symlink
1884                         if(is_link($tmp_symlink)) {
1885                             $app->system->unlink($tmp_symlink);
1886                             $app->log('Removing symlink: '.$tmp_symlink, LOGLEVEL_DEBUG);
1887                         }
1888                     }
1889                 }
1890                 // end removing symlinks
3cde19 1891             }
7fe908 1892
MC 1893             // Delete the log file directory
1894             $vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
1895             if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir, '..')) exec('rm -rf '.$vhost_logfile_dir);
1896             $app->log('Removing website logfile directory: '.$vhost_logfile_dir, LOGLEVEL_DEBUG);
1897
1898             if($data['old']['type'] == 'vhost') {
1899                 //delete the web user
1900                 $command = 'killall -u '.escapeshellcmd($data['old']['system_user']).' ; userdel';
1901                 $command .= ' '.escapeshellcmd($data['old']['system_user']);
1902                 exec($command);
1903                 if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
1904
1905             }
1906
1907             //* Remove the awstats configuration file
1908             if($data['old']['stats_type'] == 'awstats') {
1909                 $this->awstats_delete($data, $web_config);
1910             }
1911
1912             if($data['old']['type'] == 'vhostsubdomain') {
1913                 $app->system->web_folder_protection($parent_web_document_root, true);
1914             }
1915
8ab3cd 1916             if($apache_chrooted) {
7fe908 1917                 $app->services->restartServiceDelayed('httpd', 'restart');
8ab3cd 1918             } else {
T 1919                 // request a httpd reload when all records have been processed
7fe908 1920                 $app->services->restartServiceDelayed('httpd', 'reload');
58c210 1921             }
ac933e 1922
46c683 1923         }
7fe908 1924         if($data['old']['type'] != 'vhost') $app->system->web_folder_protection($data['old']['document_root'], true);
46c683 1925     }
ac933e 1926
46c683 1927     //* This function is called when a IP on the server is inserted, updated or deleted
7fe908 1928     function server_ip($event_name, $data) {
46c683 1929         global $app, $conf;
ac933e 1930
46c683 1931         // load the server configuration options
fb3339 1932         $app->uses('getconf');
J 1933         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 1934
46c683 1935         $app->load('tpl');
ac933e 1936
46c683 1937         $tpl = new tpl();
fb3339 1938         $tpl->newTemplate('apache_ispconfig.conf.master');
8133de 1939         $tpl->setVar('apache_version', $app->system->getapacheversion());
fb3339 1940         $records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
7fe908 1941
a2156e 1942         $records_out= array();
T 1943         if(is_array($records)) {
1944             foreach($records as $rec) {
1945                 if($rec['ip_type'] == 'IPv6') {
1946                     $ip_address = '['.$rec['ip_address'].']';
1947                 } else {
1948                     $ip_address = $rec['ip_address'];
1949                 }
7fe908 1950                 $ports = explode(',', $rec['virtualhost_port']);
a2156e 1951                 if(is_array($ports)) {
T 1952                     foreach($ports as $port) {
1953                         $port = intval($port);
1954                         if($port > 0 && $port < 65536 && $ip_address != '') {
1955                             $records_out[] = array('ip_address' => $ip_address, 'port' => $port);
1956                         }
1957                     }
1958                 }
1959             }
1960         }
7fe908 1961
MC 1962
a2156e 1963         if(count($records_out) > 0) {
7fe908 1964             $tpl->setLoop('ip_adresses', $records_out);
46c683 1965         }
ac933e 1966
fb3339 1967         $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
7fe908 1968         $app->system->file_put_contents($vhost_file, $tpl->grab());
MC 1969         $app->log('Writing the conf file: '.$vhost_file, LOGLEVEL_DEBUG);
46c683 1970         unset($tpl);
ac933e 1971
46c683 1972     }
7fe908 1973
524077 1974     //* Create or update the .htaccess folder protection
7fe908 1975     function web_folder_user($event_name, $data) {
524077 1976         global $app, $conf;
c69439 1977
524077 1978         $app->uses('system');
7fe908 1979
524077 1980         if($event_name == 'web_folder_user_delete') {
T 1981             $folder_id = $data['old']['web_folder_id'];
1982         } else {
1983             $folder_id = $data['new']['web_folder_id'];
1984         }
7fe908 1985
524077 1986         $folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
T 1987         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 1988
524077 1989         if(!is_array($folder) or !is_array($website)) {
7fe908 1990             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 1991             return false;
T 1992         }
7fe908 1993
MC 1994         $web_folder = 'web';
1995         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
1996
524077 1997         //* Get the folder path.
7fe908 1998         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 1999         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2000         $folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2001         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2002
524077 2003         //* Check if the resulting path is inside the docroot
7fe908 2004         if(stristr($folder_path, '..') || stristr($folder_path, './') || stristr($folder_path, '\\')) {
MC 2005             $app->log('Folder path "'.$folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
524077 2006             return false;
T 2007         }
7fe908 2008
524077 2009         //* Create the folder path, if it does not exist
8cf78b 2010         if(!is_dir($folder_path)) {
c77103 2011             $app->system->mkdirpath($folder_path);
7fe908 2012             $app->system->chown($folder_path, $website['system_user']);
MC 2013             $app->system->chgrp($folder_path, $website['system_group']);
8cf78b 2014         }
7fe908 2015
524077 2016         //* Create empty .htpasswd file, if it does not exist
T 2017         if(!is_file($folder_path.'.htpasswd')) {
4bd960 2018             $app->system->touch($folder_path.'.htpasswd');
51910d 2019             $app->system->chmod($folder_path.'.htpasswd', 0751);
7fe908 2020             $app->system->chown($folder_path.'.htpasswd', $website['system_user']);
MC 2021             $app->system->chgrp($folder_path.'.htpasswd', $website['system_group']);
2022             $app->log('Created file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2023         }
7fe908 2024
8ab3cd 2025         /*
T 2026         $auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
2027         $htpasswd_content = '';
2028         if(is_array($auth_users) && !empty($auth_users)){
2029             foreach($auth_users as $auth_user){
2030                 $htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
2031             }
2032         }
2033         $htpasswd_content = trim($htpasswd_content);
2034         @file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
2035         $app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
2036         */
7fe908 2037
8ab3cd 2038         if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
7fe908 2039             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2040             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
c69439 2041         }
7fe908 2042
524077 2043         //* Add or remove the user from .htpasswd file
T 2044         if($event_name == 'web_folder_user_delete') {
7fe908 2045             $app->system->removeLine($folder_path.'.htpasswd', $data['old']['username'].':');
MC 2046             $app->log('Removed user: '.$data['old']['username'], LOGLEVEL_DEBUG);
524077 2047         } else {
c69439 2048             if($data['new']['active'] == 'y') {
7fe908 2049                 $app->system->replaceLine($folder_path.'.htpasswd', $data['new']['username'].':', $data['new']['username'].':'.$data['new']['password'], 0, 1);
MC 2050                 $app->log('Added or updated user: '.$data['new']['username'], LOGLEVEL_DEBUG);
c69439 2051             }
524077 2052         }
7fe908 2053
MC 2054
524077 2055         //* Create the .htaccess file
8ab3cd 2056         //if(!is_file($folder_path.'.htaccess')) {
7fe908 2057         $begin_marker = '### ISPConfig folder protection begin ###';
MC 2058         $end_marker = "### ISPConfig folder protection end ###\n\n";
2059         $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
2060
2061         if(file_exists($folder_path.'.htaccess')) {
2062             $old_content = $app->system->file_get_contents($folder_path.'.htaccess');
2063
2064             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2065                 $ht_file = str_replace($matches[0], $ht_file, $old_content);
2066             } else {
2067                 $ht_file .= $old_content;
2068             }
2069         }
2070         unset($old_content);
2071
2072         $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
51910d 2073         $app->system->chmod($folder_path.'.htaccess', 0751);
7fe908 2074         $app->system->chown($folder_path.'.htaccess', $website['system_user']);
MC 2075         $app->system->chgrp($folder_path.'.htaccess', $website['system_group']);
2076         $app->log('Created/modified file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
8ab3cd 2077         //}
7fe908 2078
524077 2079     }
7fe908 2080
524077 2081     //* Remove .htaccess and .htpasswd file, when folder protection is removed
7fe908 2082     function web_folder_delete($event_name, $data) {
524077 2083         global $app, $conf;
7fe908 2084
524077 2085         $folder_id = $data['old']['web_folder_id'];
7fe908 2086
8ab3cd 2087         $folder = $data['old'];
524077 2088         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
7fe908 2089
524077 2090         if(!is_array($folder) or !is_array($website)) {
7fe908 2091             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
524077 2092             return false;
T 2093         }
7fe908 2094
MC 2095         $web_folder = 'web';
2096         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2097
524077 2098         //* Get the folder path.
7fe908 2099         if(substr($folder['path'], 0, 1) == '/') $folder['path'] = substr($folder['path'], 1);
MC 2100         if(substr($folder['path'], -1) == '/') $folder['path'] = substr($folder['path'], 0, -1);
6fb93d 2101         $folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$folder['path']);
7fe908 2102         if(substr($folder_path, -1) != '/') $folder_path .= '/';
MC 2103
524077 2104         //* Check if the resulting path is inside the docroot
7fe908 2105         if(substr($folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2106             $app->log('Folder path is outside of docroot.', LOGLEVEL_DEBUG);
524077 2107             return false;
T 2108         }
7fe908 2109
524077 2110         //* Remove .htpasswd file
T 2111         if(is_file($folder_path.'.htpasswd')) {
c77103 2112             $app->system->unlink($folder_path.'.htpasswd');
7fe908 2113             $app->log('Removed file '.$folder_path.'.htpasswd', LOGLEVEL_DEBUG);
524077 2114         }
7fe908 2115
524077 2116         //* Remove .htaccess file
T 2117         if(is_file($folder_path.'.htaccess')) {
7fe908 2118             $begin_marker = '### ISPConfig folder protection begin ###';
MC 2119             $end_marker = "### ISPConfig folder protection end ###\n\n";
2120
2121             $ht_file = $app->system->file_get_contents($folder_path.'.htaccess');
2122
2123             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2124                 $ht_file = str_replace($matches[0], '', $ht_file);
2125             } else {
2126                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2127             }
2128
2129             if(trim($ht_file) == '') {
2130                 $app->system->unlink($folder_path.'.htaccess');
2131                 $app->log('Removed file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2132             } else {
2133                 $app->system->file_put_contents($folder_path.'.htaccess', $ht_file);
2134                 $app->log('Removed protection content from file '.$folder_path.'.htaccess', LOGLEVEL_DEBUG);
2135             }
524077 2136         }
2023a7 2137     }
7fe908 2138
2023a7 2139     //* Update folder protection, when path has been changed
7fe908 2140     function web_folder_update($event_name, $data) {
2023a7 2141         global $app, $conf;
7fe908 2142
2023a7 2143         $website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
7fe908 2144
2023a7 2145         if(!is_array($website)) {
7fe908 2146             $app->log('Not able to retrieve folder or website record.', LOGLEVEL_DEBUG);
2023a7 2147             return false;
T 2148         }
7fe908 2149
MC 2150         $web_folder = 'web';
2151         if($website['type'] == 'vhostsubdomain') $web_folder = $website['web_folder'];
2152
2023a7 2153         //* Get the folder path.
7fe908 2154         if(substr($data['old']['path'], 0, 1) == '/') $data['old']['path'] = substr($data['old']['path'], 1);
MC 2155         if(substr($data['old']['path'], -1) == '/') $data['old']['path'] = substr($data['old']['path'], 0, -1);
6fb93d 2156         $old_folder_path = realpath($website['document_root'].'/' . $web_folder . '/'.$data['old']['path']);
7fe908 2157         if(substr($old_folder_path, -1) != '/') $old_folder_path .= '/';
MC 2158
2159         if(substr($data['new']['path'], 0, 1) == '/') $data['new']['path'] = substr($data['new']['path'], 1);
2160         if(substr($data['new']['path'], -1) == '/') $data['new']['path'] = substr($data['new']['path'], 0, -1);
6fb93d 2161         $new_folder_path = escapeshellcmd($website['document_root'].'/' . $web_folder . '/'.$data['new']['path']);
7fe908 2162         if(substr($new_folder_path, -1) != '/') $new_folder_path .= '/';
MC 2163
2023a7 2164         //* Check if the resulting path is inside the docroot
7fe908 2165         if(stristr($new_folder_path, '..') || stristr($new_folder_path, './') || stristr($new_folder_path, '\\')) {
MC 2166             $app->log('Folder path "'.$new_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2167             return false;
T 2168         }
7fe908 2169         if(stristr($old_folder_path, '..') || stristr($old_folder_path, './') || stristr($old_folder_path, '\\')) {
MC 2170             $app->log('Folder path "'.$old_folder_path.'" contains .. or ./.', LOGLEVEL_DEBUG);
2023a7 2171             return false;
T 2172         }
7fe908 2173
2023a7 2174         //* Check if the resulting path is inside the docroot
7fe908 2175         if(substr($old_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2176             $app->log('Old folder path '.$old_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2177             return false;
T 2178         }
7fe908 2179         if(substr($new_folder_path, 0, strlen($website['document_root'])) != $website['document_root']) {
MC 2180             $app->log('New folder path '.$new_folder_path.' is outside of docroot.', LOGLEVEL_DEBUG);
2023a7 2181             return false;
T 2182         }
7fe908 2183
2023a7 2184         //* Create the folder path, if it does not exist
c77103 2185         if(!is_dir($new_folder_path)) $app->system->mkdirpath($new_folder_path);
7fe908 2186
MC 2187         $begin_marker = '### ISPConfig folder protection begin ###';
2188         $end_marker = "### ISPConfig folder protection end ###\n\n";
2189
2023a7 2190         if($data['old']['path'] != $data['new']['path']) {
T 2191
7fe908 2192
2023a7 2193             //* move .htpasswd file
T 2194             if(is_file($old_folder_path.'.htpasswd')) {
7fe908 2195                 $app->system->rename($old_folder_path.'.htpasswd', $new_folder_path.'.htpasswd');
MC 2196                 $app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2023a7 2197             }
7fe908 2198
8ab3cd 2199             //* delete old .htaccess file
2023a7 2200             if(is_file($old_folder_path.'.htaccess')) {
7fe908 2201                 $ht_file = $app->system->file_get_contents($old_folder_path.'.htaccess');
MC 2202
2203                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2204                     $ht_file = str_replace($matches[0], '', $ht_file);
2205                 } else {
2206                     $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$old_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2207                 }
2208
2209                 if(trim($ht_file) == '') {
2210                     $app->system->unlink($old_folder_path.'.htaccess');
2211                     $app->log('Removed file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2212                 } else {
2213                     $app->system->file_put_contents($old_folder_path.'.htaccess', $ht_file);
2214                     $app->log('Removed protection content from file '.$old_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2215                 }
2023a7 2216             }
7fe908 2217
2023a7 2218         }
7fe908 2219
2023a7 2220         //* Create the .htaccess file
8ab3cd 2221         if($data['new']['active'] == 'y') {
7fe908 2222             $ht_file = $begin_marker."\nAuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user\n".$end_marker;
MC 2223
2224             if(file_exists($new_folder_path.'.htaccess')) {
2225                 $old_content = $app->system->file_get_contents($new_folder_path.'.htaccess');
2226
2227                 if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $old_content, $matches)) {
2228                     $ht_file = str_replace($matches[0], $ht_file, $old_content);
2229                 } else {
2230                     $ht_file .= $old_content;
2231                 }
2232             }
2233
2234             $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
51910d 2235             $app->system->chmod($new_folder_path.'.htaccess', 0751);
7fe908 2236             $app->system->chown($new_folder_path.'.htaccess', $website['system_user']);
MC 2237             $app->system->chgrp($new_folder_path.'.htaccess', $website['system_group']);
2238             $app->log('Created/modified file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
8433d0 2239             
TB 2240             //* Create empty .htpasswd file, if it does not exist
2241             if(!is_file($folder_path.'.htpasswd')) {
2242                 $app->system->touch($new_folder_path.'.htpasswd');
51910d 2243                 $app->system->chmod($new_folder_path.'.htpasswd', 0751);
8433d0 2244                 $app->system->chown($new_folder_path.'.htpasswd', $website['system_user']);
TB 2245                 $app->system->chgrp($new_folder_path.'.htpasswd', $website['system_group']);
2246                 $app->log('Created file '.$new_folder_path.'.htpasswd', LOGLEVEL_DEBUG);
2247             }
2023a7 2248         }
7fe908 2249
2023a7 2250         //* Remove .htaccess file
T 2251         if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
7fe908 2252             $ht_file = $app->system->file_get_contents($new_folder_path.'.htaccess');
MC 2253
2254             if(preg_match('/' . preg_quote($begin_marker, '/') . '(.*?)' . preg_quote($end_marker, '/') . '/s', $ht_file, $matches)) {
2255                 $ht_file = str_replace($matches[0], '', $ht_file);
2256             } else {
2257                 $ht_file = str_replace("AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user", '', $ht_file);
2258             }
2259
2260             if(trim($ht_file) == '') {
2261                 $app->system->unlink($new_folder_path.'.htaccess');
2262                 $app->log('Removed file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2263             } else {
2264                 $app->system->file_put_contents($new_folder_path.'.htaccess', $ht_file);
2265                 $app->log('Removed protection content from file '.$new_folder_path.'.htaccess', LOGLEVEL_DEBUG);
2266             }
2023a7 2267         }
7fe908 2268
MC 2269
524077 2270     }
7fe908 2271
MC 2272     public function ftp_user_delete($event_name, $data) {
26c0fc 2273         global $app, $conf;
7fe908 2274
26c0fc 2275         $ftpquota_file = $data['old']['dir'].'/.ftpquota';
c77103 2276         if(file_exists($ftpquota_file)) $app->system->unlink($ftpquota_file);
7fe908 2277
26c0fc 2278     }
7fe908 2279
MC 2280
ac933e 2281
V 2282     /**
2283      * This function is called when a Webdav-User is inserted, updated or deleted.
2284      *
2285      * @author Oliver Vogel
2286      * @param string $event_name
2287      * @param array $data
2288      */
7fe908 2289     public function webdav($event_name, $data) {
ac933e 2290         global $app, $conf;
7fe908 2291
52a04e 2292         /*
T 2293          * load the server configuration options
2294         */
fb3339 2295         $app->uses('getconf');
J 2296         $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
ac933e 2297
V 2298         if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
2299
2300             /*
2301              * Get additional informations
2302             */
fb3339 2303             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
ac933e 2304             $documentRoot = $sitedata['document_root'];
V 2305             $domain = $sitedata['domain'];
ca14fe 2306             $user = $sitedata['system_user'];
V 2307             $group = $sitedata['system_group'];
b67344 2308             $webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
ac933e 2309
V 2310             /* Check if this is a chrooted setup */
2311             if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
2312                 $apache_chrooted = true;
7fe908 2313                 $app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
ac933e 2314             } else {
V 2315                 $apache_chrooted = false;
2316             }
7fe908 2317
b67344 2318             //* We dont want to have relative paths here
7fe908 2319             if(stristr($webdav_user_dir, '..')  || stristr($webdav_user_dir, './')) {
MC 2320                 $app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot, LOGLEVEL_WARN);
b67344 2321                 return false;
T 2322             }
7fe908 2323
b67344 2324             //* Check if the resulting path exists if yes, if it is inside the docroot
7fe908 2325             if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir), 0, strlen($documentRoot)) != $documentRoot) {
MC 2326                 $app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot, LOGLEVEL_WARN);
b67344 2327                 return false;
T 2328             }
ac933e 2329
V 2330             /*
2331              * First the webdav-root - folder has to exist
2332             */
b67344 2333             if(!is_dir($webdav_user_dir)) {
7fe908 2334                 $app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.', LOGLEVEL_DEBUG);
c77103 2335                 $app->system->mkdirpath($webdav_user_dir);
ac933e 2336             }
V 2337
2338             /*
ca14fe 2339              * The webdav - Root needs the group/user as owner and the apache as read and write
ac933e 2340             */
c77103 2341             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
T 2342             //$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
7fe908 2343             $app->system->chown($documentRoot . '/webdav', $user);
MC 2344             $app->system->chgrp($documentRoot . '/webdav', $group);
2345             $app->system->chmod($documentRoot . '/webdav', 0770);
ac933e 2346
V 2347             /*
ca14fe 2348              * The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
V 2349              * pwd-files are owned by root)
ac933e 2350             */
c77103 2351             //$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
T 2352             //$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
7fe908 2353             $app->system->chown($webdav_user_dir, $user);
MC 2354             $app->system->chgrp($webdav_user_dir, $group);
2355             $app->system->chmod($webdav_user_dir, 0770);
ca14fe 2356
V 2357             /*
2358              * if the user is active, we have to write/update the password - file
2359              * if the user is inactive, we have to inactivate the user by removing the user from the file
2360             */
2361             if ($data['new']['active'] == 'y') {
b67344 2362                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
ca14fe 2363             }
V 2364             else {
2365                 /* empty pwd removes the user! */
b67344 2366                 $this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
ca14fe 2367             }
ac933e 2368
V 2369             /*
2370              * Next step, patch the vhost - file
2371             */
fb3339 2372             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
ac933e 2373             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
ca14fe 2374
ac933e 2375             /*
V 2376              * Last, restart apache
2377             */
2378             if($apache_chrooted) {
7fe908 2379                 $app->services->restartServiceDelayed('httpd', 'restart');
ac933e 2380             } else {
V 2381                 // request a httpd reload when all records have been processed
7fe908 2382                 $app->services->restartServiceDelayed('httpd', 'reload');
ac933e 2383             }
V 2384
2385         }
2386
2387         if ($event_name == 'webdav_user_delete') {
2388             /*
2389              * Get additional informations
2390             */
fb3339 2391             $sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
ac933e 2392             $documentRoot = $sitedata['document_root'];
52a04e 2393             $domain = $sitedata['domain'];
ac933e 2394
V 2395             /*
2396              * We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
2397              * So the only thing, we have to do, is to delete the user from the password-file
ca14fe 2398             */
ac933e 2399             $this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
7fe908 2400
52a04e 2401             /*
T 2402              * Next step, patch the vhost - file
2403             */
fb3339 2404             $vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
52a04e 2405             $this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
7fe908 2406
52a04e 2407             /*
T 2408              * Last, restart apache
2409             */
2410             if($apache_chrooted) {
7fe908 2411                 $app->services->restartServiceDelayed('httpd', 'restart');
52a04e 2412             } else {
T 2413                 // request a httpd reload when all records have been processed
7fe908 2414                 $app->services->restartServiceDelayed('httpd', 'reload');
52a04e 2415             }
ac933e 2416         }
V 2417     }
2418
2419
2420     /**
2421      * This function writes the htdigest - files used by webdav and digest
ca14fe 2422      * more info: see http://riceball.com/d/node/424
ac933e 2423      * @author Oliver Vogel
V 2424      * @param string $filename The name of the digest-file
2425      * @param string $username The name of the webdav-user
2426      * @param string $authname The name of the realm
ca14fe 2427      * @param string $pwd      The password-hash of the user
ac933e 2428      */
ca14fe 2429     private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
4bd960 2430         global $app;
7fe908 2431
ac933e 2432         $changed = false;
c77103 2433         if(is_file($filename) && !is_link($filename)) {
0ff3f1 2434             $in = fopen($filename, 'r');
T 2435             $output = '';
2436             /*
2437             * read line by line and search for the username and authname
2438             */
2439             while (preg_match("/:/", $line = fgets($in))) {
2440                 $line = rtrim($line);
2441                 $tmp = explode(':', $line);
2442                 if ($tmp[0] == $username && $tmp[1] == $authname) {
2443                     /*
2444                     * found the user. delete or change it?
2445                     */
2446                     if ($pwdhash != '') {
2447                         $output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
7fe908 2448                     }
0ff3f1 2449                     $changed = true;
T 2450                 }
2451                 else {
2452                     $output .= $line . "\n";
2453                 }
ac933e 2454             }
0ff3f1 2455             fclose($in);
ac933e 2456         }
V 2457         /*
2458          * if we didn't change anything, we have to add the new user at the end of the file
2459         */
2460         if (!$changed) {
f17dab 2461             $output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
ac933e 2462         }
7fe908 2463
ac933e 2464
V 2465         /*
2466          * Now lets write the new file
2467         */
52a04e 2468         if(trim($output) == '') {
c77103 2469             $app->system->unlink($filename);
52a04e 2470         } else {
c77103 2471             $app->system->file_put_contents($filename, $output);
52a04e 2472         }
ac933e 2473     }
V 2474
2475     /**
2476      * This function patches the vhost-file and adds all webdav - user.
2477      * This function is written, because the creation of the vhost - file is sophisticated and
2478      * i don't want to make it more "heavy" by also adding this code too...
2479      * @author Oliver Vogel
2480      * @param string $fileName The Name of the .vhost-File (path included)
2481      * @param string $webdavRoot The root of the webdav-folder
2482      */
2483     private function _patchVhostWebdav($fileName, $webdavRoot) {
c77103 2484         global $app;
ac933e 2485         $in = fopen($fileName, 'r');
V 2486         $output = '';
2487         $inWebdavSection = false;
2488
2489         /*
2490          * read line by line and search for the username and authname
2491         */
2492         while ($line = fgets($in)) {
2493             /*
2494              *  is the "replace-comment" found...
2495             */
2496             if (trim($line) == '# WEBDAV BEGIN') {
2497                 /*
2498                  * The begin of the webdav - section is found, so ignore all lines til the end  is found
2499                 */
2500                 $inWebdavSection = true;
2501
2502                 $output .= "      # WEBDAV BEGIN\n";
2503
2504                 /*
2505                  * add all the webdav-dirs to the webdav-section
2506                 */
fb3a98 2507                 $files = @scandir($webdavRoot);
T 2508                 if(is_array($files)) {
7fe908 2509                     foreach($files as $file) {
MC 2510                         if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest' && preg_match("/^[a-zA-Z0-9\-_\.]*$/", $file)) {
2511                             /*
ac933e 2512                          * found a htdigest - file, so add it to webdav
V 2513                         */
7fe908 2514                             $fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
MC 2515                             $output .= "\n";
2516                             // $output .= "      Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2517                             // $output .= "      <Location /" . $fn . ">\n";
2518                             $output .= "      Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
2519                             $output .= "      <Location /webdav/" . $fn . ">\n";
2520                             $output .= "        DAV On\n";
2521                             $output .= '        BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
2522                             $output .= "        AuthType Digest\n";
2523                             $output .= "        AuthName \"" . $fn . "\"\n";
2524                             $output .= "        AuthUserFile " . $webdavRoot . '/' . $file . "\n";
2525                             $output .= "        Require valid-user \n";
2526                             $output .= "        Options +Indexes \n";
2527                             $output .= "        Order allow,deny \n";
2528                             $output .= "        Allow from all \n";
2529                             $output .= "      </Location> \n";
2530                         }
ac933e 2531                     }
fb3a98 2532                 }
ac933e 2533             }
V 2534             /*
2535              *  is the "replace-comment-end" found...
2536             */
2537             if (trim($line) == '# WEBDAV END') {
2538                 /*
2539                  * The end of the webdav - section is found, so stop ignoring
2540                 */
2541                 $inWebdavSection = false;
2542             }
2543
2544             /*
2545              * Write the line to the output, if it is not in the section
2546             */
2547             if (!$inWebdavSection) {
2548                 $output .= $line;
2549             }
2550         }
2551         fclose($in);
2552
2553         /*
2554          * Now lets write the new file
2555         */
c77103 2556         $app->system->file_put_contents($fileName, $output);
ac933e 2557
V 2558     }
7fe908 2559
58c210 2560     //* Update the awstats configuration file
7fe908 2561     private function awstats_update ($data, $web_config) {
58c210 2562         global $app;
7fe908 2563
MC 2564         $web_folder = $data['new']['web_folder'];
2565         if($data['new']['type'] == 'vhost') $web_folder = 'web';
2a6eac 2566         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2567
6fb93d 2568         if(!is_dir($data['new']['document_root']."/" . $web_folder . "/stats/")) mkdir($data['new']['document_root']."/" . $web_folder . "/stats");
fb3339 2569         if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
J 2570             if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2571                 $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
58c210 2572             }
7fe908 2573
58c210 2574             $content = '';
2a6eac 2575             $content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n";
fb3339 2576             $content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
J 2577             $content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
2578             $content .= "HostAliases=\"www.".$data['new']['domain']."  localhost 127.0.0.1\"\n";
7fe908 2579
MC 2580             $app->system->file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', $content);
2581             $app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2582         }
7fe908 2583
6fb93d 2584         if(is_file($data['new']['document_root']."/" . $web_folder . "/stats/index.html")) $app->system->unlink($data['new']['document_root']."/" . $web_folder . "/stats/index.html");
a464e1 2585         if(file_exists("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master")) {
7fe908 2586             $app->system->copy("/usr/local/ispconfig/server/conf-custom/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2587         } else {
7fe908 2588             $app->system->copy("/usr/local/ispconfig/server/conf/awstats_index.php.master", $data['new']['document_root']."/" . $web_folder . "/stats/index.php");
a464e1 2589         }
58c210 2590     }
7fe908 2591
58c210 2592     //* Delete the awstats configuration file
7fe908 2593     private function awstats_delete ($data, $web_config) {
58c210 2594         global $app;
7fe908 2595
58c210 2596         $awstats_conf_dir = $web_config['awstats_conf_dir'];
7fe908 2597
fb3339 2598         if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
c77103 2599             $app->system->unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
7fe908 2600             $app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf', LOGLEVEL_DEBUG);
58c210 2601         }
T 2602     }
7fe908 2603
274362 2604     //* Update the PHP-FPM pool configuration file
7fe908 2605     private function php_fpm_pool_update ($data, $web_config, $pool_dir, $pool_name, $socket_dir) {
274362 2606         global $app, $conf;
F 2607         //$reload = false;
7fe908 2608
62e4b3 2609         if($data['new']['php'] == 'php-fpm'){
F 2610             if(trim($data['new']['fastcgi_php_version']) != ''){
2611                 $default_php_fpm = false;
2612                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['new']['fastcgi_php_version']));
7fe908 2613                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2614             } else {
F 2615                 $default_php_fpm = true;
2616             }
274362 2617         } else {
62e4b3 2618             if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
F 2619                 $default_php_fpm = false;
2620                 list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 2621                 if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
62e4b3 2622             } else {
F 2623                 $default_php_fpm = true;
2624             }
274362 2625         }
7fe908 2626
274362 2627         $app->uses("getconf");
F 2628         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2629
274362 2630         if($data['new']['php'] != 'php-fpm'){
F 2631             if(@is_file($pool_dir.$pool_name.'.conf')){
c77103 2632                 $app->system->unlink($pool_dir.$pool_name.'.conf');
274362 2633                 //$reload = true;
F 2634             }
2635             if($data['old']['php'] == 'php-fpm'){
2636                 if(!$default_php_fpm){
7fe908 2637                     $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2638                 } else {
7fe908 2639                     $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2640                 }
F 2641             }
2642             //if($reload == true) $app->services->restartService('php-fpm','reload');
2643             return;
2644         }
7fe908 2645
274362 2646         $app->load('tpl');
F 2647         $tpl = new tpl();
2648         $tpl->newTemplate('php_fpm_pool.conf.master');
8133de 2649         $tpl->setVar('apache_version', $app->system->getapacheversion());
MC 2650         
274362 2651         if($data['new']['php_fpm_use_socket'] == 'y'){
F 2652             $use_tcp = 0;
2653             $use_socket = 1;
c77103 2654             if(!is_dir($socket_dir)) $app->system->mkdirpath($socket_dir);
274362 2655         } else {
F 2656             $use_tcp = 1;
2657             $use_socket = 0;
2658         }
2659         $tpl->setVar('use_tcp', $use_tcp);
2660         $tpl->setVar('use_socket', $use_socket);
7fe908 2661
274362 2662         $fpm_socket = $socket_dir.$pool_name.'.sock';
F 2663         $tpl->setVar('fpm_socket', $fpm_socket);
b491ad 2664         $tpl->setVar('fpm_listen_mode', '0660');
7fe908 2665
274362 2666         $tpl->setVar('fpm_pool', $pool_name);
F 2667         $tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
2668         $tpl->setVar('fpm_user', $data['new']['system_user']);
2669         $tpl->setVar('fpm_group', $data['new']['system_group']);
dd7ce4 2670         $tpl->setVar('pm', $data['new']['pm']);
274362 2671         $tpl->setVar('pm_max_children', $data['new']['pm_max_children']);
F 2672         $tpl->setVar('pm_start_servers', $data['new']['pm_start_servers']);
2673         $tpl->setVar('pm_min_spare_servers', $data['new']['pm_min_spare_servers']);
2674         $tpl->setVar('pm_max_spare_servers', $data['new']['pm_max_spare_servers']);
dd7ce4 2675         $tpl->setVar('pm_process_idle_timeout', $data['new']['pm_process_idle_timeout']);
F 2676         $tpl->setVar('pm_max_requests', $data['new']['pm_max_requests']);
274362 2677         $tpl->setVar('document_root', $data['new']['document_root']);
7fe908 2678         $tpl->setVar('security_level', $web_config['security_level']);
f63910 2679         $tpl->setVar('domain', $data['new']['domain']);
274362 2680         $php_open_basedir = ($data['new']['php_open_basedir'] == '')?escapeshellcmd($data['new']['document_root']):escapeshellcmd($data['new']['php_open_basedir']);
F 2681         $tpl->setVar('php_open_basedir', $php_open_basedir);
2682         if($php_open_basedir != ''){
2683             $tpl->setVar('enable_php_open_basedir', '');
2684         } else {
2685             $tpl->setVar('enable_php_open_basedir', ';');
2686         }
7fe908 2687
274362 2688         // Custom php.ini settings
F 2689         $final_php_ini_settings = array();
2690         $custom_php_ini_settings = trim($data['new']['custom_php_ini']);
2691         if($custom_php_ini_settings != ''){
2692             // Make sure we only have Unix linebreaks
2693             $custom_php_ini_settings = str_replace("\r\n", "\n", $custom_php_ini_settings);
2694             $custom_php_ini_settings = str_replace("\r", "\n", $custom_php_ini_settings);
2695             $ini_settings = explode("\n", $custom_php_ini_settings);
2696             if(is_array($ini_settings) && !empty($ini_settings)){
2697                 foreach($ini_settings as $ini_setting){
254a4a 2698                     $ini_setting = trim($ini_setting);
7fe908 2699                     if(substr($ini_setting, 0, 1) == ';') continue;
MC 2700                     if(substr($ini_setting, 0, 1) == '#') continue;
2701                     if(substr($ini_setting, 0, 2) == '//') continue;
03cc01 2702                     list($key, $value) = explode('=', $ini_setting, 2);
1d6097 2703                     $value = trim($value);
FT 2704                     if($value != ''){
254a4a 2705                         $key = trim($key);
F 2706                         switch (strtolower($value)) {
7fe908 2707                         case '0':
MC 2708                             // PHP-FPM might complain about invalid boolean value if you use 0
2709                             $value = 'off';
2710                         case '1':
2711                         case 'on':
2712                         case 'off':
2713                         case 'true':
2714                         case 'false':
2715                         case 'yes':
2716                         case 'no':
2717                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_flag['.$key.'] = '.$value);
2718                             break;
2719                         default:
2720                             $final_php_ini_settings[] = array('ini_setting' => 'php_admin_value['.$key.'] = '.$value);
274362 2721                         }
254a4a 2722                     }
274362 2723                 }
F 2724             }
2725         }
7fe908 2726
274362 2727         $tpl->setLoop('custom_php_ini_settings', $final_php_ini_settings);
7fe908 2728
MC 2729         $app->system->file_put_contents($pool_dir.$pool_name.'.conf', $tpl->grab());
2730         $app->log('Writing the PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
274362 2731         unset($tpl);
7fe908 2732
274362 2733         // delete pool in all other PHP versions
F 2734         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2735         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2736         if($default_pool_dir != $pool_dir){
F 2737             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2738                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2739                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2740                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2741             }
F 2742         }
2743         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$conf["server_id"]);
2744         if(is_array($php_versions) && !empty($php_versions)){
2745             foreach($php_versions as $php_version){
7fe908 2746                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2747                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2748                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2749                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2750                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2751                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2752                     }
F 2753                 }
2754             }
2755         }
2756         // Reload current PHP-FPM after all others
2757         sleep(1);
2758         if(!$default_php_fpm){
7fe908 2759             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2760         } else {
7fe908 2761             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2762         }
7fe908 2763
274362 2764         //$reload = true;
F 2765
2766         //if($reload == true) $app->services->restartService('php-fpm','reload');
2767     }
7fe908 2768
274362 2769     //* Delete the PHP-FPM pool configuration file
7fe908 2770     private function php_fpm_pool_delete ($data, $web_config) {
274362 2771         global $app, $conf;
7fe908 2772
62e4b3 2773         if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
274362 2774             $default_php_fpm = false;
F 2775             list($custom_php_fpm_name, $custom_php_fpm_init_script, $custom_php_fpm_ini_dir, $custom_php_fpm_pool_dir) = explode(':', trim($data['old']['fastcgi_php_version']));
7fe908 2776             if(substr($custom_php_fpm_ini_dir, -1) != '/') $custom_php_fpm_ini_dir .= '/';
274362 2777         } else {
F 2778             $default_php_fpm = true;
2779         }
7fe908 2780
274362 2781         if($default_php_fpm){
F 2782             $pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
2783         } else {
2784             $pool_dir = $custom_php_fpm_pool_dir;
2785         }
7fe908 2786
MC 2787         if(substr($pool_dir, -1) != '/') $pool_dir .= '/';
274362 2788         $pool_name = 'web'.$data['old']['domain_id'];
7fe908 2789
274362 2790         if ( @is_file($pool_dir.$pool_name.'.conf') ) {
c77103 2791             $app->system->unlink($pool_dir.$pool_name.'.conf');
7fe908 2792             $app->log('Removed PHP-FPM config file: '.$pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2793
274362 2794             //$app->services->restartService('php-fpm','reload');
F 2795         }
7fe908 2796
274362 2797         // delete pool in all other PHP versions
F 2798         $default_pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
7fe908 2799         if(substr($default_pool_dir, -1) != '/') $default_pool_dir .= '/';
274362 2800         if($default_pool_dir != $pool_dir){
F 2801             if ( @is_file($default_pool_dir.$pool_name.'.conf') ) {
7fe908 2802                 $app->system->unlink($default_pool_dir.$pool_name.'.conf');
MC 2803                 $app->log('Removed PHP-FPM config file: '.$default_pool_dir.$pool_name.'.conf', LOGLEVEL_DEBUG);
2804                 $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2805             }
7fe908 2806         }
274362 2807         $php_versions = $app->db->queryAllRecords("SELECT * FROM server_php WHERE php_fpm_init_script != '' AND php_fpm_ini_dir != '' AND php_fpm_pool_dir != '' AND server_id = ".$data['old']['server_id']);
F 2808         if(is_array($php_versions) && !empty($php_versions)){
2809             foreach($php_versions as $php_version){
7fe908 2810                 if(substr($php_version['php_fpm_pool_dir'], -1) != '/') $php_version['php_fpm_pool_dir'] .= '/';
274362 2811                 if($php_version['php_fpm_pool_dir'] != $pool_dir){
F 2812                     if ( @is_file($php_version['php_fpm_pool_dir'].$pool_name.'.conf') ) {
c77103 2813                         $app->system->unlink($php_version['php_fpm_pool_dir'].$pool_name.'.conf');
7fe908 2814                         $app->log('Removed PHP-FPM config file: '.$php_version['php_fpm_pool_dir'].$pool_name.'.conf', LOGLEVEL_DEBUG);
MC 2815                         $app->services->restartService('php-fpm', 'reload:'.$php_version['php_fpm_init_script']);
274362 2816                     }
F 2817                 }
2818             }
2819         }
7fe908 2820
274362 2821         // Reload current PHP-FPM after all others
F 2822         sleep(1);
2823         if(!$default_php_fpm){
7fe908 2824             $app->services->restartService('php-fpm', 'reload:'.$custom_php_fpm_init_script);
274362 2825         } else {
7fe908 2826             $app->services->restartService('php-fpm', 'reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
274362 2827         }
F 2828     }
7fe908 2829
MC 2830     function client_delete($event_name, $data) {
1ca823 2831         global $app, $conf;
7fe908 2832
1ca823 2833         $app->uses("getconf");
T 2834         $web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
7fe908 2835
1ca823 2836         $client_id = intval($data['old']['client_id']);
T 2837         if($client_id > 0) {
7fe908 2838
1ca823 2839             $client_dir = $web_config['website_basedir'].'/clients/client'.$client_id;
7fe908 2840             if(is_dir($client_dir) && !stristr($client_dir, '..')) {
72695f 2841                 // remove symlinks from $client_dir
7fe908 2842                 $files = array_diff(scandir($client_dir), array('.', '..'));
72695f 2843                 if(is_array($files) && !empty($files)){
T 2844                     foreach($files as $file){
2845                         if(is_link($client_dir.'/'.$file)){
2846                             unlink($client_dir.'/'.$file);
7fe908 2847                             $app->log('Removed symlink: '.$client_dir.'/'.$file, LOGLEVEL_DEBUG);
72695f 2848                         }
T 2849                     }
2850                 }
7fe908 2851
1ca823 2852                 @rmdir($client_dir);
7fe908 2853                 $app->log('Removed client directory: '.$client_dir, LOGLEVEL_DEBUG);
1ca823 2854             }
7fe908 2855
615a0a 2856             if($app->system->is_group('client'.$client_id)){
T 2857                 $this->_exec('groupdel client'.$client_id);
7fe908 2858                 $app->log('Removed group client'.$client_id, LOGLEVEL_DEBUG);
615a0a 2859             }
1ca823 2860         }
7fe908 2861
1ca823 2862     }
ac933e 2863
1c40af 2864     //* Wrapper for exec function for easier debugging
T 2865     private function _exec($command) {
2866         global $app;
7fe908 2867         $app->log('exec: '.$command, LOGLEVEL_DEBUG);
1c40af 2868         exec($command);
T 2869     }
7ed741 2870
7fe908 2871     private function _checkTcp ($host, $port) {
MC 2872
2873         $fp = @fsockopen($host, $port, $errno, $errstr, 2);
7ed741 2874
T 2875         if ($fp) {
2876             fclose($fp);
2877             return true;
2878         } else {
2879             return false;
2880         }
2881     }
ac933e 2882
552178 2883     public function create_relative_link($f, $t) {
bfcdef 2884         global $app;
7fe908 2885
552178 2886         // $from already exists
M 2887         $from = realpath($f);
2888
2889         // realpath requires the traced file to exist - so, lets touch it first, then remove
c77103 2890         @$app->system->unlink($t); touch($t);
552178 2891         $to = realpath($t);
c77103 2892         @$app->system->unlink($t);
552178 2893
M 2894         // Remove from the left side matching path elements from $from and $to
2895         // and get path elements counts
2896         $a1 = explode('/', $from); $a2 = explode('/', $to);
2897         for ($c = 0; $a1[$c] == $a2[$c]; $c++) {
2898             unset($a1[$c]); unset($a2[$c]);
2899         }
2900         $cfrom = implode('/', $a1);
2901
2902         // Check if a path is fully a subpath of another - no way to create symlink in the case
2903         if (count($a1) == 0 || count($a2) == 0) return false;
2904
2905         // Add ($cnt_to-1) number of "../" elements to left side of $cfrom
2906         for ($c = 0; $c < (count($a2)-1); $c++) { $cfrom = '../'.$cfrom; }
2907
2908         return symlink($cfrom, $to);
2909     }
46c683 2910
7fe908 2911     private function _rewrite_quote($string) {
MC 2912         return str_replace(array('.', '*', '?', '+'), array('\\.', '\\*', '\\?', '\\+'), $string);
2913     }
2914
2915     private function _is_url($string) {
2916         return preg_match('/^(f|ht)tp(s)?:\/\//i', $string);
2917     }
2918
bfcdef 2919     private function get_seo_redirects($web, $prefix = ''){
T 2920         $seo_redirects = array();
7fe908 2921
bfcdef 2922         if(substr($web['domain'], 0, 2) === '*.') $web['subdomain'] = '*';
7fe908 2923
bfcdef 2924         if($web['subdomain'] == 'www' || $web['subdomain'] == '*'){
T 2925             if($web['seo_redirect'] == 'non_www_to_www'){
2926                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2927                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2928                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2929             }
2930             if($web['seo_redirect'] == '*_domain_tld_to_www_domain_tld'){
2931                 // ^(example\.com|(?!\bwww\b)\.example\.com)$
2932                 // ^(example\.com|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.example\.com))$
2933                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '('.str_replace('.', '\.', $web['domain']).'|((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.'.str_replace('.', '\.', $web['domain']).'))';
2934                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2935                 $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2936             }
2937             if($web['seo_redirect'] == '*_to_www_domain_tld'){
2938                 $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2939                 $seo_redirects[$prefix.'seo_redirect_target_domain'] = 'www.'.$web['domain'];
2940                 $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2941             }
2942         }
2943         if($web['seo_redirect'] == 'www_to_non_www'){
2944             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = 'www\.'.str_replace('.', '\.', $web['domain']);
2945             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2946             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2947         }
2948         if($web['seo_redirect'] == '*_domain_tld_to_domain_tld'){
2949             // ^(.+)\.example\.com$
2950             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = '(.+)\.'.str_replace('.', '\.', $web['domain']);
2951             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2952             $seo_redirects[$prefix.'seo_redirect_operator'] = '';
2953         }
2954         if($web['seo_redirect'] == '*_to_domain_tld'){
2955             $seo_redirects[$prefix.'seo_redirect_origin_domain'] = str_replace('.', '\.', $web['domain']);
2956             $seo_redirects[$prefix.'seo_redirect_target_domain'] = $web['domain'];
2957             $seo_redirects[$prefix.'seo_redirect_operator'] = '!';
2958         }
2959         return $seo_redirects;
2960     }
7fe908 2961
46c683 2962 } // end class
T 2963
c09f04 2964 ?>