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