apache2_plugin.inc.php 150 KB
Newer Older
1
2
3
<?php

/*
4
Copyright (c) 2007 - 2012, Till Brehm, projektfarm Gmbh
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
      this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
      this list of conditions and the following disclaimer in the documentation
      and/or other materials provided with the distribution.
    * Neither the name of ISPConfig nor the names of its contributors
      may be used to endorse or promote products derived from this software without
      specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

class apache2_plugin {
32

33
34
	var $plugin_name = 'apache2_plugin';
	var $class_name = 'apache2_plugin';
35

36
37
	// private variables
	var $action = '';
38
	var $ssl_certificate_changed = false;
39

40
41
42
43
	//* This function is called during ispconfig installation to determine
	//  if a symlink shall be created for this plugin.
	function onInstall() {
		global $conf;
44

45
46
47
48
49
		if($conf['services']['web'] == true) {
			return true;
		} else {
			return false;
		}
50

51
	}
52
53


54
55
56
	/*
	 	This function is called when the plugin is loaded
	*/
57

58
59
	function onLoad() {
		global $app;
60

61
62
63
		/*
		Register for the events
		*/
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
		$app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'ssl');
		$app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'ssl');
		$app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'ssl');

		$app->plugins->registerEvent('web_domain_insert', $this->plugin_name, 'insert');
		$app->plugins->registerEvent('web_domain_update', $this->plugin_name, 'update');
		$app->plugins->registerEvent('web_domain_delete', $this->plugin_name, 'delete');

		$app->plugins->registerEvent('server_ip_insert', $this->plugin_name, 'server_ip');
		$app->plugins->registerEvent('server_ip_update', $this->plugin_name, 'server_ip');
		$app->plugins->registerEvent('server_ip_delete', $this->plugin_name, 'server_ip');

		$app->plugins->registerEvent('webdav_user_insert', $this->plugin_name, 'webdav');
		$app->plugins->registerEvent('webdav_user_update', $this->plugin_name, 'webdav');
		$app->plugins->registerEvent('webdav_user_delete', $this->plugin_name, 'webdav');

		$app->plugins->registerEvent('client_delete', $this->plugin_name, 'client_delete');

		$app->plugins->registerEvent('web_folder_user_insert', $this->plugin_name, 'web_folder_user');
		$app->plugins->registerEvent('web_folder_user_update', $this->plugin_name, 'web_folder_user');
		$app->plugins->registerEvent('web_folder_user_delete', $this->plugin_name, 'web_folder_user');

		$app->plugins->registerEvent('web_folder_update', $this->plugin_name, 'web_folder_update');
		$app->plugins->registerEvent('web_folder_delete', $this->plugin_name, 'web_folder_delete');

		$app->plugins->registerEvent('ftp_user_delete', $this->plugin_name, 'ftp_user_delete');

		$app->plugins->registerAction('php_ini_changed', $this->plugin_name, 'php_ini_changed');
92
	}
93
94
95
96
97
98
99
100
101

	// check for php.ini changes


	// Handle php.ini changes
	function php_ini_changed($event_name, $data) {
		global $app, $conf;

		$app->uses('getconf');
102
103
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
		$fastcgi_config = $app->getconf->get_server_config($conf['server_id'], 'fastcgi');
104
105

		/* $data contains an array with these keys:
106
         * file -> full path of changed php_ini
107
         * mode -> web_domain php modes to change (mod, fast-cgi, php-fpm, hhvm or '' for all except 'mod')
108
109
         * php_version -> php ini path that changed (additional php versions)
         */
110

111
		$param = '';
112
113
114
115
116
117
		$qrystr = "SELECT * FROM web_domain WHERE custom_php_ini != ''";
		if($data['mode'] == 'mod') {
			$qrystr .= " AND php = 'mod'";
		} elseif($data['mode'] == 'fast-cgi') {
			$qrystr .= " AND php = 'fast-cgi'";
			if($data['php_version']) {
118
119
				$qrystr .= " AND fastcgi_php_version LIKE ?";
				$param = '%:' . $data['php_version'];
120
121
122
123
			}
		} elseif($data['mode'] == 'php-fpm') {
			$qrystr .= " AND php = 'php-fpm'";
			if($data['php_version']) {
124
125
				$qrystr .= " AND fastcgi_php_version LIKE ?";
				$param = '%:' . $data['php_version'] . ':%';
126
			}
127
128
129
		} elseif($data['mode'] == 'hhvm') {
			$qrystr .= " AND php = 'hhvm'";
			if($data['php_version']) {
130
131
				$qrystr .= " AND fastcgi_php_version LIKE ?";
				$param = '%:' . $data['php_version'] . ':%';
132
			}
133
134
135
136
137
138
		} else {
			$qrystr .= " AND php != 'mod' AND php != 'fast-cgi'";
		}


		//** Get all the webs
139
		$web_domains = $app->db->queryAllRecords($qrystr, $param);
140
141
142
		foreach($web_domains as $web_data) {
			$custom_php_ini_dir = $web_config['website_basedir'].'/conf/'.$web_data['system_user'];
			$web_folder = 'web';
Dominik's avatar
Dominik committed
143
			if($web_data['type'] == 'vhostsubdomain' || $web_data['type'] == 'vhostalias') {
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
				$web_folder = $web_data['web_folder'];
				$custom_php_ini_dir .= '_' . $web_folder;
			}
			if(!is_dir($web_config['website_basedir'].'/conf')) $app->system->mkdir($web_config['website_basedir'].'/conf');


			if(!is_dir($custom_php_ini_dir)) $app->system->mkdir($custom_php_ini_dir);
			$php_ini_content = '';
			if($web_data['php'] == 'mod') {
				$master_php_ini_path = $web_config['php_ini_path_apache'];
			} else {
				if($web_data['php'] == 'fast-cgi' && file_exists($fastcgi_config["fastcgi_phpini_path"])) {
					$master_php_ini_path = $fastcgi_config["fastcgi_phpini_path"];
				} else {
					$master_php_ini_path = $web_config['php_ini_path_cgi'];
				}
			}
			if($master_php_ini_path != '' && substr($master_php_ini_path, -7) == 'php.ini' && is_file($master_php_ini_path)) {
				$php_ini_content .= $app->system->file_get_contents($master_php_ini_path)."\n";
			}
Marius Cramer's avatar
Marius Cramer committed
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
			
			if(intval($web_data['directive_snippets_id']) > 0){
				$snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'nginx' AND active = 'y' AND customer_viewable = 'y'", intval($web_data['directive_snippets_id']));
				if(isset($snippet['required_php_snippets']) && trim($snippet['required_php_snippets']) != ''){
					$required_php_snippets = explode(',', trim($snippet['required_php_snippets']));
					if(is_array($required_php_snippets) && !empty($required_php_snippets)){
						foreach($required_php_snippets as $required_php_snippet){
							$required_php_snippet = intval($required_php_snippet);
							if($required_php_snippet > 0){
								$php_snippet = $app->db->queryOneRecord("SELECT * FROM directive_snippets WHERE directive_snippets_id = ? AND type = 'php' AND active = 'y'", $required_php_snippet);
								$php_snippet['snippet'] = trim($php_snippet['snippet']);
								if($php_snippet['snippet'] != ''){
									$web_data['custom_php_ini'] .= "\n".$php_snippet['snippet'];
								}
							}
						}
					}
				}
			}
		
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
			$php_ini_content .= str_replace("\r", '', trim($web_data['custom_php_ini']));
			$app->system->file_put_contents($custom_php_ini_dir.'/php.ini', $php_ini_content);
			$app->log('Info: rewrote custom php.ini for web ' . $web_data['domain_id'] . ' (' . $web_data['domain'] . ').', LOGLEVEL_DEBUG);
		}

		if(count($web_domains) > 0) {
			//* We do not check the apache config here - we only changed the php.ini
			//* Check if this is a chrooted setup
			if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
				$apache_chrooted = true;
				$app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
			} else {
				$apache_chrooted = false;
			}

			$app->log('Info: rewrote all php.ini and reloading apache now.', LOGLEVEL_DEBUG);
			if($apache_chrooted) {
				$app->services->restartServiceDelayed('httpd', 'restart');
			} else {
				// request a httpd reload when all records have been processed
				$app->services->restartServiceDelayed('httpd', 'reload');
			}
		} else {
			$app->log('Info: No webs affected by php.ini change.', LOGLEVEL_DEBUG);
		}
	}

211
	// Handle the creation of SSL certificates
212
	function ssl($event_name, $data) {
213
		global $app, $conf;
214

215
		$app->uses('system');
216
217
218
219
220

		// load the server configuration options
		$app->uses('getconf');
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
		if ($web_config['CA_path']!='' && !file_exists($web_config['CA_path'].'/openssl.cnf'))
221
222
			$app->log("CA path error, file does not exist:".$web_config['CA_path'].'/openssl.cnf', LOGLEVEL_ERROR);

223
		//* Only vhosts can have a ssl cert
Dominik's avatar
Dominik committed
224
		if($data["new"]["type"] != "vhost" && $data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") return;
225

226
227
		// if(!is_dir($data['new']['document_root'].'/ssl')) exec('mkdir -p '.$data['new']['document_root'].'/ssl');
		if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
228

229
230
231
232
233
234
		$ssl_dir = $data['new']['document_root'].'/ssl';
		$domain = $data['new']['ssl_domain'];
		$key_file = $ssl_dir.'/'.$domain.'.key.org';
		$key_file2 = $ssl_dir.'/'.$domain.'.key';
		$csr_file = $ssl_dir.'/'.$domain.'.csr';
		$crt_file = $ssl_dir.'/'.$domain.'.crt';
235

236
237
		//* Create a SSL Certificate, but only if this is not a mirror server.
		if($data['new']['ssl_action'] == 'create' && $conf['mirror_server_id'] == 0) {
238

239
			$this->ssl_certificate_changed = true;
240

tbrehm's avatar
tbrehm committed
241
			//* Rename files if they exist
242
			if(file_exists($key_file)){
243
244
				$app->system->rename($key_file, $key_file.'.bak');
				$app->system->chmod($key_file.'.bak', 0400);
245
246
			}
			if(file_exists($key_file2)){
247
248
				$app->system->rename($key_file2, $key_file2.'.bak');
				$app->system->chmod($key_file2.'.bak', 0400);
249
			}
250
251
252
			if(file_exists($csr_file)) $app->system->rename($csr_file, $csr_file.'.bak');
			if(file_exists($crt_file)) $app->system->rename($crt_file, $crt_file.'.bak');

253
			$rand_file = $ssl_dir.'/random_file';
254
			$rand_data = md5(uniqid(microtime(), 1));
255
			for($i=0; $i<1000; $i++) {
256
257
258
259
				$rand_data .= md5(uniqid(microtime(), 1));
				$rand_data .= md5(uniqid(microtime(), 1));
				$rand_data .= md5(uniqid(microtime(), 1));
				$rand_data .= md5(uniqid(microtime(), 1));
260
			}
261
			$app->system->file_put_contents($rand_file, $rand_data);
262

263
			$ssl_password = substr(md5(uniqid(microtime(), 1)), 0, 15);
264

265
266
267
			$ssl_cnf = "        RANDFILE               = $rand_file

        [ req ]
268
        default_bits           = 2048
269
		default_md             = sha256
270
271
272
273
274
275
276
        default_keyfile        = keyfile.pem
        distinguished_name     = req_distinguished_name
        attributes             = req_attributes
        prompt                 = no
        output_password        = $ssl_password

        [ req_distinguished_name ]
tbrehm's avatar
tbrehm committed
277
278
279
280
281
        C                      = ".trim($data['new']['ssl_country'])."
        ST                     = ".trim($data['new']['ssl_state'])."
        L                      = ".trim($data['new']['ssl_locality'])."
        O                      = ".trim($data['new']['ssl_organisation'])."
        OU                     = ".trim($data['new']['ssl_organisation_unit'])."
282
283
284
285
286
        CN                     = $domain
        emailAddress           = webmaster@".$data['new']['domain']."

        [ req_attributes ]
        challengePassword              = A challenge password";
287

288
			$ssl_cnf_file = $ssl_dir.'/openssl.conf';
289
			$app->system->file_put_contents($ssl_cnf_file, $ssl_cnf);
290

291
292
			$rand_file = escapeshellcmd($rand_file);
			$key_file = escapeshellcmd($key_file);
293
			$openssl_cmd_key_file = $key_file;
294
			if(substr($domain, 0, 2) == '*.' && strpos($key_file, '/ssl/\*.') !== false) $key_file = str_replace('/ssl/\*.', '/ssl/*.', $key_file); // wildcard certificate
295
			$key_file2 = escapeshellcmd($key_file2);
296
			$openssl_cmd_key_file2 = $key_file2;
297
			if(substr($domain, 0, 2) == '*.' && strpos($key_file2, '/ssl/\*.') !== false) $key_file2 = str_replace('/ssl/\*.', '/ssl/*.', $key_file2); // wildcard certificate
298
299
			$ssl_days = 3650;
			$csr_file = escapeshellcmd($csr_file);
300
			$openssl_cmd_csr_file = $csr_file;
301
			if(substr($domain, 0, 2) == '*.' && strpos($csr_file, '/ssl/\*.') !== false) $csr_file = str_replace('/ssl/\*.', '/ssl/*.', $csr_file); // wildcard certificate
302
303
			$config_file = escapeshellcmd($ssl_cnf_file);
			$crt_file = escapeshellcmd($crt_file);
304
			$openssl_cmd_crt_file = $crt_file;
305
			if(substr($domain, 0, 2) == '*.' && strpos($crt_file, '/ssl/\*.') !== false) $crt_file = str_replace('/ssl/\*.', '/ssl/*.', $crt_file); // wildcard certificate
306

307
			if(is_file($ssl_cnf_file) && !is_link($ssl_cnf_file)) {
308

309
				exec("openssl genrsa -des3 -rand $rand_file -passout pass:$ssl_password -out $openssl_cmd_key_file 2048");
310
				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");
311
				exec("openssl rsa -passin pass:$ssl_password -in $openssl_cmd_key_file -out $openssl_cmd_key_file2");
312
313

				if(file_exists($web_config['CA_path'].'/openssl.cnf'))
314
				{
315
					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");
316
					$app->log("Creating CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
317
					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);
318
				};
319
				if (@filesize($crt_file)==0 || !file_exists($crt_file)){
320
					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 ");
321
					$app->log("Creating self-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
322
				};
323

324
			}
325

326
327
			$app->system->chmod($key_file, 0400);
			$app->system->chmod($key_file2, 0400);
328
329
			@$app->system->unlink($config_file);
			@$app->system->unlink($rand_file);
330
331
332
			$ssl_request = $app->system->file_get_contents($csr_file);
			$ssl_cert = $app->system->file_get_contents($crt_file);
			$ssl_key2 = $app->system->file_get_contents($key_file2);
333
			/* Update the DB of the (local) Server */
334
335
			$app->db->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
336
			/* Update also the master-DB of the Server-Farm */
337
338
			$app->dbmaster->query("UPDATE web_domain SET ssl_request = ?, ssl_cert = ?, ssl_key = ? WHERE domain = ?", $ssl_request, $ssl_cert, $ssl_key2, $data['new']['domain']);
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
339
		}
340

341
		//* Save a SSL certificate to disk
342
		if($data["new"]["ssl_action"] == 'save') {
343
			$this->ssl_certificate_changed = true;
344
			$ssl_dir = $data["new"]["document_root"]."/ssl";
345
			$domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
346
			$key_file = $ssl_dir.'/'.$domain.'.key.org';
347
			$key_file2 = $ssl_dir.'/'.$domain.'.key';
348
349
350
			$csr_file = $ssl_dir.'/'.$domain.".csr";
			$crt_file = $ssl_dir.'/'.$domain.".crt";
			$bundle_file = $ssl_dir.'/'.$domain.".bundle";
351

352
			//* Backup files
353
			if(file_exists($key_file)){
354
355
				$app->system->copy($key_file, $key_file.'~');
				$app->system->chmod($key_file.'~', 0400);
356
357
			}
			if(file_exists($key_file2)){
358
359
				$app->system->copy($key_file2, $key_file2.'~');
				$app->system->chmod($key_file2.'~', 0400);
360
			}
361
362
363
364
			if(file_exists($csr_file)) $app->system->copy($csr_file, $csr_file.'~');
			if(file_exists($crt_file)) $app->system->copy($crt_file, $crt_file.'~');
			if(file_exists($bundle_file)) $app->system->copy($bundle_file, $bundle_file.'~');

365
			//* Write new ssl files
366
			if(trim($data["new"]["ssl_request"]) != '') $app->system->file_put_contents($csr_file, $data["new"]["ssl_request"]);
367
368
369
370
371
372
373
374
375
			if(version_compare($app->system->getapacheversion(true), '2.4.8', '>=')) {
				$tmp_data = '';
				if(trim($data["new"]["ssl_cert"]) != '') $tmp_data .= $data["new"]["ssl_cert"] . "\n";
				if(trim($data["new"]["ssl_bundle"]) != '') $tmp_data .= $data["new"]["ssl_bundle"];
				if(trim($tmp_data) != '') $app->system->file_put_contents($crt_file, $tmp_data);
			} else {
				if(trim($data["new"]["ssl_cert"]) != '') $app->system->file_put_contents($crt_file, $data["new"]["ssl_cert"]);
				if(trim($data["new"]["ssl_bundle"]) != '') $app->system->file_put_contents($bundle_file, $data["new"]["ssl_bundle"]);
			}
376

377
378
			//* Write the key file, if field is empty then import the key into the db
			if(trim($data["new"]["ssl_key"]) != '') {
379
380
				$app->system->file_put_contents($key_file2, $data["new"]["ssl_key"]);
				$app->system->chmod($key_file2, 0400);
381
			} else {
382
				$ssl_key2 = $app->system->file_get_contents($key_file2);
383
				/* Update the DB of the (local) Server */
384
				$app->db->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
385
				/* Update also the master-DB of the Server-Farm */
386
				$app->dbmaster->query("UPDATE web_domain SET ssl_key = ? WHERE domain = ?", $ssl_key2, $data['new']['domain']);
387
			}
388

389
			/* Update the DB of the (local) Server */
390
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
391

392
			/* Update also the master-DB of the Server-Farm */
393
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
394
			$app->log('Saving SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
395
		}
396

397
		//* Delete a SSL certificate
398
399
		if($data['new']['ssl_action'] == 'del') {
			$ssl_dir = $data['new']['document_root'].'/ssl';
400
			$domain = ($data["new"]["ssl_domain"] != '')?$data["new"]["ssl_domain"]:$data["new"]["domain"];
401
402
403
			$csr_file = $ssl_dir.'/'.$domain.'.csr';
			$crt_file = $ssl_dir.'/'.$domain.'.crt';
			$bundle_file = $ssl_dir.'/'.$domain.'.bundle';
404
			if(file_exists($web_config['CA_path'].'/openssl.cnf') && !is_link($web_config['CA_path'].'/openssl.cnf'))
405
			{
406
				exec("openssl ca -batch -config ".$web_config['CA_path']."/openssl.cnf -passin pass:".$web_config['CA_pass']." -revoke ".escapeshellcmd($crt_file));
407
408
				$app->log("Revoking CA-signed SSL Cert for: $domain", LOGLEVEL_DEBUG);
			};
409
410
411
			$app->system->unlink($csr_file);
			$app->system->unlink($crt_file);
			$app->system->unlink($bundle_file);
412
			/* Update the DB of the (local) Server */
413
414
			$app->db->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
			$app->db->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
415
			/* Update also the master-DB of the Server-Farm */
416
417
			$app->dbmaster->query("UPDATE web_domain SET ssl_request = '', ssl_cert = '' WHERE domain = ?", $data['new']['domain']);
			$app->dbmaster->query("UPDATE web_domain SET ssl_action = '' WHERE domain = ?", $data['new']['domain']);
418
			$app->log('Deleting SSL Cert for: '.$domain, LOGLEVEL_DEBUG);
419
		}
420

421
	}
422
423


424
	function insert($event_name, $data) {
425
		global $app, $conf;
426

427
428
		$this->action = 'insert';
		// just run the update function
429
		$this->update($event_name, $data);
430
431


432
	}
433
434


435
	function update($event_name, $data) {
436
		global $app, $conf;
437

438
		if($this->action != 'insert') $this->action = 'update';
439

Dominik's avatar
Dominik committed
440
		if($data['new']['type'] != 'vhost' && $data['new']['type'] != 'vhostsubdomain' && $data['new']['type'] != 'vhostalias' && $data['new']['parent_domain_id'] > 0) {
441

442
443
			$old_parent_domain_id = intval($data['old']['parent_domain_id']);
			$new_parent_domain_id = intval($data['new']['parent_domain_id']);
444

445
			// If the parent_domain_id has been changed, we will have to update the old site as well.
446
			if($this->action == 'update' && $data['new']['parent_domain_id'] != $data['old']['parent_domain_id']) {
447
				$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ?', $old_parent_domain_id, 'y');
448
449
				$data['new'] = $tmp;
				$data['old'] = $tmp;
450
				$this->action = 'update';
451
				$this->update($event_name, $data);
452
			}
453

454
			// This is not a vhost, so we need to update the parent record instead.
455
			$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = ? AND active = ', $new_parent_domain_id, 'y');
456
457
			$data['new'] = $tmp;
			$data['old'] = $tmp;
458
459
			$this->action = 'update';
		}
460

461
		// load the server configuration options
462
463
		$app->uses('getconf');
		$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
464

465
		//* Check if this is a chrooted setup
466
		if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
467
			$apache_chrooted = true;
468
			$app->log('Info: Apache is chrooted.', LOGLEVEL_DEBUG);
469
470
471
		} else {
			$apache_chrooted = false;
		}
472

473
		if($data['new']['document_root'] == '') {
Dominik's avatar
Dominik committed
474
			if($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') $app->log('document_root not set', LOGLEVEL_WARN);
475
476
			return 0;
		}
477
478
479
		if($app->system->is_allowed_user($data['new']['system_user'], $app->system->is_user($data['new']['system_user']), true) == false
			|| $app->system->is_allowed_group($data['new']['system_group'], $app->system->is_group($data['new']['system_group']), true) == false) {
			$app->log('Websites cannot be owned by the root user or group. User: '.$data['new']['system_user'].' Group: '.$data['new']['system_group'], LOGLEVEL_WARN);
480
481
			return 0;
		}
tbrehm's avatar
tbrehm committed
482
		if(trim($data['new']['domain']) == '') {
483
			$app->log('domain is empty', LOGLEVEL_WARN);
tbrehm's avatar
tbrehm committed
484
485
			return 0;
		}
486
487
488

		$web_folder = 'web';
		$log_folder = 'log';
489
490
		$old_web_folder = 'web';
		$old_log_folder = 'log';
Dominik's avatar
Dominik committed
491
		if($data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') {
492
			// new one
493
			$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['new']['parent_domain_id']);
494
495
496
497
498
			$subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['new']['domain']);
			if($subdomain_host == '') $subdomain_host = 'web'.$data['new']['domain_id'];
			$web_folder = $data['new']['web_folder'];
			$log_folder .= '/' . $subdomain_host;
			unset($tmp);
499
500
501
			
			if(isset($data['old']['parent_domain_id'])) {
				// old one
502
				$tmp = $app->db->queryOneRecord('SELECT `domain` FROM web_domain WHERE domain_id = ?', $data['old']['parent_domain_id']);
503
504
505
506
507
508
				$subdomain_host = preg_replace('/^(.*)\.' . preg_quote($tmp['domain'], '/') . '$/', '$1', $data['old']['domain']);
				if($subdomain_host == '') $subdomain_host = 'web'.$data['old']['domain_id'];
				$old_web_folder = $data['old']['web_folder'];
				$old_log_folder .= '/' . $subdomain_host;
				unset($tmp);
			}
509
		}
510

511
512
		// Create group and user, if not exist
		$app->uses('system');
513

514
515
516
517
518
519
		if($web_config['connect_userid_to_webid'] == 'y') {
			//* Calculate the uid and gid
			$connect_userid_to_webid_start = ($web_config['connect_userid_to_webid_start'] < 1000)?1000:intval($web_config['connect_userid_to_webid_start']);
			$fixed_uid_gid = intval($connect_userid_to_webid_start + $data['new']['domain_id']);
			$fixed_uid_param = '--uid '.$fixed_uid_gid;
			$fixed_gid_param = '--gid '.$fixed_uid_gid;
520

521
522
523
524
525
526
527
528
529
530
531
			//* Check if a ispconfigend user and group exists and create them
			if(!$app->system->is_group('ispconfigend')) {
				exec('groupadd --gid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
			}
			if(!$app->system->is_user('ispconfigend')) {
				exec('useradd -g ispconfigend -d /usr/local/ispconfig --uid '.($connect_userid_to_webid_start + 10000).' ispconfigend');
			}
		} else {
			$fixed_uid_param = '';
			$fixed_gid_param = '';
		}
532
533
534

		$groupname = escapeshellcmd($data['new']['system_group']);
		if($data['new']['system_group'] != '' && !$app->system->is_group($data['new']['system_group'])) {
535
			exec('groupadd '.$fixed_gid_param.' '.$groupname);
536
			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' groupadd '.$groupname);
537
			$app->log('Adding the group: '.$groupname, LOGLEVEL_DEBUG);
538
539
540
541
		}

		$username = escapeshellcmd($data['new']['system_user']);
		if($data['new']['system_user'] != '' && !$app->system->is_user($data['new']['system_user'])) {
542
543
544
545
546
547
548
			if($web_config['add_web_users_to_sshusers_group'] == 'y') {
				exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param -G sshusers $username -s /bin/false");
				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");
			} else {
				exec('useradd -d '.escapeshellcmd($data['new']['document_root'])." -g $groupname $fixed_uid_param $username -s /bin/false");
				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");
			}
549
			$app->log('Adding the user: '.$username, LOGLEVEL_DEBUG);
550
		}
551

552
		//* If the client of the site has been changed, we have a change of the document root
553
		if($this->action == 'update' && $data['new']['document_root'] != $data['old']['document_root']) {
554

555
			//* Get the old client ID
556
			$old_client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['old']['sys_groupid']);
557
			$old_client_id = intval($old_client['client_id']);
558
			unset($old_client);
559

560
			//* Remove the old symlinks
561
			$tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
562
563
			if(is_array($tmp_symlinks_array)) {
				foreach($tmp_symlinks_array as $tmp_symlink) {
564
565
					$tmp_symlink = str_replace('[client_id]', $old_client_id, $tmp_symlink);
					$tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
566
567
568
					// Remove trailing slash
					if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
					// create the symlinks, if not exist
569
					if(is_link($tmp_symlink)) {
570
						exec('rm -f '.escapeshellcmd($tmp_symlink));
571
						$app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
572
573
574
					}
				}
			}
575

576
			//* Remove protection of old folders
577
578
			$app->system->web_folder_protection($data['old']['document_root'], false);

Dominik's avatar
Dominik committed
579
			if($data["new"]["type"] != "vhostsubdomain" && $data["new"]["type"] != "vhostalias") {
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
				//* Move the site data
				$tmp_docroot = explode('/', $data['new']['document_root']);
				unset($tmp_docroot[count($tmp_docroot)-1]);
				$new_dir = implode('/', $tmp_docroot);

				$tmp_docroot = explode('/', $data['old']['document_root']);
				unset($tmp_docroot[count($tmp_docroot)-1]);
				$old_dir = implode('/', $tmp_docroot);

				//* 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
				if(@is_dir($data['new']['document_root'])) {
					$app->system->web_folder_protection($data['new']['document_root'], false);
					$app->system->rename($data['new']['document_root'], $data['new']['document_root'].'_bak_'.date('Y_m_d_H_i_s'));
					$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);
				}
595
596
597
				
				//* Unmount the old log directory bfore we move the log dir
				exec('umount '.escapeshellcmd($old_dir.'/log'));
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

				//* Create new base directory, if it does not exist yet
				if(!is_dir($new_dir)) $app->system->mkdirpath($new_dir);
				$app->system->web_folder_protection($data['old']['document_root'], false);
				exec('mv '.escapeshellarg($data['old']['document_root']).' '.escapeshellarg($new_dir));
				//$app->system->rename($data['old']['document_root'],$new_dir);
				$app->log('Moving site to new document root: mv '.$data['old']['document_root'].' '.$new_dir, LOGLEVEL_DEBUG);

				// Handle the change in php_open_basedir
				$data['new']['php_open_basedir'] = str_replace($data['old']['document_root'], $data['new']['document_root'], $data['old']['php_open_basedir']);

				//* Change the owner of the website files to the new website owner
				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);

				//* Change the home directory and group of the website user
				$command = 'killall -u '.escapeshellcmd($data['new']['system_user']).' ; usermod';
				$command .= ' --home '.escapeshellcmd($data['new']['document_root']);
				$command .= ' --gid '.escapeshellcmd($data['new']['system_group']);
				$command .= ' '.escapeshellcmd($data['new']['system_user']).' 2>/dev/null';
				exec($command);
			}

620
			if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
621

622
			//* Change the log mount
623
			/*
624
			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
625
			$app->system->removeLine('/etc/fstab', $fstab_line);
626
			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
627
			$app->system->removeLine('/etc/fstab', $fstab_line);
628
629
630
631
632
633
634
635
636
637
638
639
640
			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind,nobootwait';
			$app->system->removeLine('/etc/fstab', $fstab_line);
			*/
			
			$fstab_line_old = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
			
			if($web_config['network_filesystem'] == 'y') {
				$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
				$app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
			} else {
				$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait    0 0';
				$app->system->replaceLine('/etc/fstab', $fstab_line_old, $fstab_line, 0, 1);
			}
641
642
			
			exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
643
			
644
		}
645

646
		//print_r($data);
647

648
		// Check if the directories are there and create them if necessary.
649
650
		$app->system->web_folder_protection($data['new']['document_root'], false);

651
652
653
		if(!is_dir($data['new']['document_root'].'/' . $web_folder)) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder);
		if(!is_dir($data['new']['document_root'].'/' . $web_folder . '/error') and $data['new']['errordocs']) $app->system->mkdirpath($data['new']['document_root'].'/' . $web_folder . '/error');
		//if(!is_dir($data['new']['document_root'].'/'.$log_folder)) exec('mkdir -p '.$data['new']['document_root'].'/'.$log_folder);
654
655
656
657
		if(!is_dir($data['new']['document_root'].'/ssl')) $app->system->mkdirpath($data['new']['document_root'].'/ssl');
		if(!is_dir($data['new']['document_root'].'/cgi-bin')) $app->system->mkdirpath($data['new']['document_root'].'/cgi-bin');
		if(!is_dir($data['new']['document_root'].'/tmp')) $app->system->mkdirpath($data['new']['document_root'].'/tmp');
		if(!is_dir($data['new']['document_root'].'/webdav')) $app->system->mkdirpath($data['new']['document_root'].'/webdav');
658

659
660
661
		//* Create the new private directory
		if(!is_dir($data['new']['document_root'].'/private')) {
			$app->system->mkdirpath($data['new']['document_root'].'/private');
662
663
664
			$app->system->chmod($data['new']['document_root'].'/private', 0710);
			$app->system->chown($data['new']['document_root'].'/private', $username);
			$app->system->chgrp($data['new']['document_root'].'/private', $groupname);
665
		}
666
667


668
		// Remove the symlink for the site, if site is renamed
669
670
		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
			if(is_dir('/var/log/ispconfig/httpd/'.$data['old']['domain'])) exec('rm -rf /var/log/ispconfig/httpd/'.$data['old']['domain']);
671
			if(is_link($data['old']['document_root'].'/'.$old_log_folder)) $app->system->unlink($data['old']['document_root'].'/'.$old_log_folder);
672

673
			//* remove old log mount
674
			$fstab_line = '/var/log/ispconfig/httpd/'.$data['old']['domain'].' '.$data['old']['document_root'].'/'.$old_log_folder.'    none    bind';
675
676
			$app->system->removeLine('/etc/fstab', $fstab_line);

677
			//* Unmount log directory
678
			exec('umount '.escapeshellarg($data['old']['document_root'].'/'.$old_log_folder));
679
		}
680

681
		//* Create the log dir if nescessary and mount it
682
		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)) {
683
			if(is_link($data['new']['document_root'].'/'.$log_folder)) unlink($data['new']['document_root'].'/'.$log_folder);
684
			if(!is_dir('/var/log/ispconfig/httpd/'.$data['new']['domain'])) exec('mkdir -p /var/log/ispconfig/httpd/'.$data['new']['domain']);
mcramer's avatar
mcramer committed
685
			$app->system->mkdirpath($data['new']['document_root'].'/'.$log_folder);
686
687
688
			$app->system->chown($data['new']['document_root'].'/'.$log_folder, 'root');
			$app->system->chgrp($data['new']['document_root'].'/'.$log_folder, 'root');
			$app->system->chmod($data['new']['document_root'].'/'.$log_folder, 0755);
689
			exec('mount --bind '.escapeshellarg('/var/log/ispconfig/httpd/'.$data['new']['domain']).' '.escapeshellarg($data['new']['document_root'].'/'.$log_folder));
690
			//* add mountpoint to fstab
691
			$fstab_line = '/var/log/ispconfig/httpd/'.$data['new']['domain'].' '.$data['new']['document_root'].'/'.$log_folder.'    none    bind,nobootwait,_netdev    0 0';
692
			$app->system->replaceLine('/etc/fstab', $fstab_line, $fstab_line, 1, 1);
693
		}
694
695

		$app->system->web_folder_protection($data['new']['document_root'], true);
696

697
		// Get the client ID
698
		$client = $app->dbmaster->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = ?', $data['new']['sys_groupid']);
699
		$client_id = intval($client['client_id']);
700
		unset($client);
701

702
		// Remove old symlinks, if site is renamed
703
		if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
704
			$tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
705
706
			if(is_array($tmp_symlinks_array)) {
				foreach($tmp_symlinks_array as $tmp_symlink) {
707
708
					$tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
					$tmp_symlink = str_replace('[website_domain]', $data['old']['domain'], $tmp_symlink);
709
710
711
712
					// Remove trailing slash
					if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
					// remove the symlinks, if not exist
					if(is_link($tmp_symlink)) {
713
						exec('rm -f '.escapeshellcmd($tmp_symlink));
714
						$app->log('Removed symlink: rm -f '.$tmp_symlink, LOGLEVEL_DEBUG);
715
716
717
718
					}
				}
			}
		}
719

720
		// Create the symlinks for the sites
721
		$tmp_symlinks_array = explode(':', $web_config['website_symlinks']);
722
723
		if(is_array($tmp_symlinks_array)) {
			foreach($tmp_symlinks_array as $tmp_symlink) {
724
725
				$tmp_symlink = str_replace('[client_id]', $client_id, $tmp_symlink);
				$tmp_symlink = str_replace('[website_domain]', $data['new']['domain'], $tmp_symlink);
726
727
728
				// Remove trailing slash
				if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
				//* Remove symlink if target folder has been changed.
729
				if($data['old']['document_root'] != '' && $data['old']['document_root'] != $data['new']['document_root'] && is_link($tmp_symlink)) {
730
					$app->system->unlink($tmp_symlink);
731
732
733
				}
				// create the symlinks, if not exist
				if(!is_link($tmp_symlink)) {
734
					//     exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
735
736
737
738
739
740
					if ($web_config["website_symlinks_rel"] == 'y') {
						$this->create_relative_link(escapeshellcmd($data["new"]["document_root"]), escapeshellcmd($tmp_symlink));
					} else {
						exec("ln -s ".escapeshellcmd($data["new"]["document_root"])."/ ".escapeshellcmd($tmp_symlink));
					}

741
					$app->log('Creating symlink: ln -s '.$data['new']['document_root'].'/ '.$tmp_symlink, LOGLEVEL_DEBUG);
742
743
744
				}
			}
		}
745
746


latham's avatar
latham committed
747

748
749
750
751
752
753
		// Install the Standard or Custom Error, Index and other related files
		// /usr/local/ispconfig/server/conf is for the standard files
		// /usr/local/ispconfig/server/conf-custom is for the custom files
		// setting a local var here

		// normally $conf['templates'] = "/usr/local/ispconfig/server/conf";
Dominik's avatar
Dominik committed
754
		if($this->action == 'insert' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias')) {
755
756

			// Copy the error pages
757
			if($data['new']['errordocs']) {
758
				$error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
759
760
				if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
761
762
				}
				else {
763
764
					if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
						exec('cp '. $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
765
766
					}
					else {
767
						exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
768
769
					}
				}
770
				exec('chmod -R a+r '.$error_page_path);
771
772
			}

773
774
775
776
777
778
779
780
781
782
783
784
785
			if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2))) {
				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');

				if(is_file($conf['rootpath'] . '/conf-custom/index/favicon.ico')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
				}
				if(is_file($conf['rootpath'] . '/conf-custom/index/robots.txt')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
				}
				if(is_file($conf['rootpath'] . '/conf-custom/index/.htaccess')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
				}
			}
786
			else {
787
				if (file_exists($conf['rootpath'] . '/conf-custom/index/standard_index.html')) {
788
					exec('cp ' . $conf['rootpath'] . '/conf-custom/index/standard_index.html '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
789
790
				}
				else {
791
					exec('cp ' . $conf['rootpath'] . '/conf/index/standard_index.html_'.substr(escapeshellcmd($conf['language']), 0, 2).' '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/index.html');
792
793
794
					if(is_file($conf['rootpath'] . '/conf/index/favicon.ico')) exec('cp ' . $conf['rootpath'] . '/conf/index/favicon.ico '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
					if(is_file($conf['rootpath'] . '/conf/index/robots.txt')) exec('cp ' . $conf['rootpath'] . '/conf/index/robots.txt '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
					if(is_file($conf['rootpath'] . '/conf/index/.htaccess')) exec('cp ' . $conf['rootpath'] . '/conf/index/.htaccess '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
795
796
				}
			}
797
			exec('chmod -R a+r '.escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/');
798
799

			//** Copy the error documents on update when the error document checkbox has been activated and was deactivated before
Dominik's avatar
Dominik committed
800
		} elseif ($this->action == 'update' && ($data['new']['type'] == 'vhost' || $data['new']['type'] == 'vhostsubdomain' || $data['new']['type'] == 'vhostalias') && $data['old']['errordocs'] == 0 && $data['new']['errordocs'] == 1) {
801

802
			$error_page_path = escapeshellcmd($data['new']['document_root']).'/' . $web_folder . '/error/';
803
804
			if (file_exists($conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2))) {
				exec('cp ' . $conf['rootpath'] . '/conf-custom/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
805
806
			}
			else {
807
808
				if (file_exists($conf['rootpath'] . '/conf-custom/error/400.html')) {
					exec('cp ' . $conf['rootpath'] . '/conf-custom/error/*.html '.$error_page_path);
809
810
				}
				else {
811
					exec('cp ' . $conf['rootpath'] . '/conf/error/'.substr(escapeshellcmd($conf['language']), 0, 2).'/* '.$error_page_path);
812
813
				}
			}
814
			exec('chmod -R a+r '.$error_page_path);
latham's avatar
latham committed
815
			exec('chown -R '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$error_page_path);
816
		}  // end copy error docs
817

Dominik's avatar
Dominik committed
818
		// Set the quota for the user, but only for vhosts, not vhostsubdomains or vhostalias
819
		if($username != '' && $app->system->is_user($username) && $data['new']['type'] == 'vhost') {
820
821
			if($data['new']['hd_quota'] > 0) {
				$blocks_soft = $data['new']['hd_quota'] * 1024;
822
823
824
825
				$blocks_hard = $blocks_soft + 1024