Newer
Older
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']));
if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
} else {
$default_php_fpm = true;
}
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
}
if($default_php_fpm){
$pool_dir = escapeshellcmd($web_config['php_fpm_pool_dir']);
} else {
$pool_dir = $custom_php_fpm_pool_dir;
}
if(substr($pool_dir,-1) != '/') $pool_dir .= '/';
$pool_name = 'web'.$data['new']['domain_id'];
$socket_dir = escapeshellcmd($web_config['php_fpm_socket_dir']);
if(substr($socket_dir,-1) != '/') $socket_dir .= '/';
if($data['new']['php_fpm_use_socket'] == 'y'){
$use_tcp = 0;
$use_socket = 1;
} else {
$use_tcp = 1;
$use_socket = 0;
}
$tpl->setVar('use_tcp', $use_tcp);
$tpl->setVar('use_socket', $use_socket);
$fpm_socket = $socket_dir.$pool_name.'.sock';
$tpl->setVar('fpm_socket', $fpm_socket);
$tpl->setVar('fpm_port', $web_config['php_fpm_start_port'] + $data['new']['domain_id'] - 1);
/**
* install cgi starter script and add script alias to config.
* This is needed to allow cgi with suexec (to do so, we need a bin in the document-path!)
* first we create the script directory if not already created, then copy over the starter script.
* TODO: we have to fetch the data from the server-settings.
*/
if ($data['new']['php'] == 'cgi') {
//$cgi_config = $app->getconf->get_server_config($conf['server_id'], 'cgi');
$cgi_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
$cgi_config['cgi_starter_script'] = 'php-cgi-starter';
$cgi_config['cgi_bin'] = '/usr/bin/php-cgi';
$cgi_starter_path = str_replace('[system_user]',$data['new']['system_user'],$cgi_config['cgi_starter_path']);
$cgi_starter_path = str_replace('[client_id]',$client_id,$cgi_starter_path);
exec('mkdir -p '.escapeshellcmd($cgi_starter_path));
exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.escapeshellcmd($cgi_starter_path));
$app->log('Creating cgi starter script directory: '.$cgi_starter_path,LOGLEVEL_DEBUG);
}
$cgi_tpl = new tpl();
$cgi_tpl->newTemplate('php-cgi-starter.master');
// This works because PHP "rewrites" a symlink to the physical path
$php_open_basedir = ($data['new']['php_open_basedir'] == '')?$data['new']['document_root']:$data['new']['php_open_basedir'];
$cgi_tpl->setVar('open_basedir', escapeshellcmd($php_open_basedir));
$cgi_tpl->setVar('document_root', escapeshellcmd($data['new']['document_root']));
// This will NOT work!
//$cgi_tpl->setVar('open_basedir', '/var/www/' . $data['new']['domain']);
$cgi_tpl->setVar('php_cgi_bin',$cgi_config['cgi_bin']);
$cgi_tpl->setVar('security_level',$web_config['security_level']);
$cgi_tpl->setVar('has_custom_php_ini',$has_custom_php_ini);
if($has_custom_php_ini) {
$cgi_tpl->setVar('php_ini_path',escapeshellcmd($custom_php_ini_dir));
} else {
$cgi_tpl->setVar('php_ini_path',escapeshellcmd($fastcgi_config['fastcgi_phpini_path']));
$cgi_starter_script = escapeshellcmd($cgi_starter_path.$cgi_config['cgi_starter_script']);
file_put_contents($cgi_starter_script,$cgi_tpl->grab());
unset($cgi_tpl);
$app->log('Creating cgi starter script: '.$cgi_starter_script,LOGLEVEL_DEBUG);
exec('chmod 755 '.$cgi_starter_script);
exec('chown '.$data['new']['system_user'].':'.$data['new']['system_group'].' '.$cgi_starter_script);
$tpl->setVar('cgi_starter_path',$cgi_starter_path);
$tpl->setVar('cgi_starter_script',$cgi_config['cgi_starter_script']);
}
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['new']['domain'].'.vhost');
//* Make a backup copy of vhost file
tbrehm
committed
if(file_exists($vhost_file)) copy($vhost_file,$vhost_file.'~');
//* create empty vhost array
$vhosts = array();
//* Add vhost for ipv4 IP
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 0, 'port' => 80);
}
//* Add vhost for ipv4 IP with SSL
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)) {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => $data['new']['ip_address'], 'ssl_enabled' => 1, 'port' => '443');
}
$app->log('Enable SSL for: '.$domain,LOGLEVEL_DEBUG);
}
//* Add vhost for IPv6 IP
if($data['new']['ipv6_address'] != '') {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80, 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 0, 'port' => 80);
}
//* Add vhost for ipv6 IP with SSL
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)) {
if(count($rewrite_rules) > 0){
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443', 'redirects' => $rewrite_rules);
} else {
$vhosts[] = array('ip_address' => '['.$data['new']['ipv6_address'].']', 'ssl_enabled' => 1, 'port' => '443');
}
$app->log('Enable SSL for IPv6: '.$domain,LOGLEVEL_DEBUG);
}
}
//* Set the vhost loop
$tpl->setLoop('vhosts',$vhosts);
//* Write vhost file
file_put_contents($vhost_file,$tpl->grab());
$app->log('Writing the vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
unset($tpl);
/*
* maybe we have some webdav - user. If so, add them...
*/
$this->_patchVhostWebdav($vhost_file, $data['new']['document_root'] . '/webdav');
//* Set the symlink to enable the vhost
//* First we check if there is a old type of symlink and remove it
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['new']['domain'].'.vhost');
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
if(is_link($vhost_symlink)) unlink($vhost_symlink);
//* Remove old or changed symlinks
if($data['new']['subdomain'] != $data['old']['subdomain'] or $data['new']['active'] == 'n') {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
}
//* New symlink
if($data['new']['subdomain'] == '*') {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['new']['domain'].'.vhost');
} else {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['new']['domain'].'.vhost');
}
if($data['new']['active'] == 'y' && !is_link($vhost_symlink)) {
symlink($vhost_file,$vhost_symlink);
$app->log('Creating symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
// remove old symlink and vhost file, if domain name of the site has changed
if($this->action == 'update' && $data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain']) {
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)) {
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
unlink($vhost_file);
$app->log('Removing file: '.$vhost_file,LOGLEVEL_DEBUG);
//* Create .htaccess and .htpasswd file for website statistics
if(!is_file($data['new']['document_root'].'/web/stats/.htaccess') or $data['old']['document_root'] != $data['new']['document_root']) {
if(!is_dir($data['new']['document_root'].'/web/stats')) mkdir($data['new']['document_root'].'/web/stats');
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$data['new']['document_root']."/.htpasswd_stats\nrequire valid-user";
file_put_contents($data['new']['document_root'].'/web/stats/.htaccess',$ht_file);
chmod($data['new']['document_root'].'/web/stats/.htaccess',0755);
unset($ht_file);
}
if(!is_file($data['new']['document_root'].'/.htpasswd_stats') || $data['new']['stats_password'] != $data['old']['stats_password']) {
if(trim($data['new']['stats_password']) != '') {
$htp_file = 'admin:'.trim($data['new']['stats_password']);
file_put_contents($data['new']['document_root'].'/.htpasswd_stats',$htp_file);
chmod($data['new']['document_root'].'/.htpasswd_stats',0755);
unset($htp_file);
}
}
//* Create awstats configuration
if($data['new']['stats_type'] == 'awstats' && $data['new']['type'] == 'vhost') {
$this->awstats_update($data,$web_config);
}
$this->php_fpm_pool_update($data,$web_config,$pool_dir,$pool_name,$socket_dir);
if($web_config['check_apache_config'] == 'y') {
//* Test if apache starts with the new configuration file
$apache_online_status_before_restart = $this->_checkTcp('localhost',80);
$app->log('Apache status is: '.$apache_online_status_before_restart,LOGLEVEL_DEBUG);
$app->services->restartService('httpd','restart');
// wait a few seconds, before we test the apache status again
sleep(2);
//* Check if apache restarted successfully if it was online before
$apache_online_status_after_restart = $this->_checkTcp('localhost',80);
$app->log('Apache online status after restart is: '.$apache_online_status_after_restart,LOGLEVEL_DEBUG);
if($apache_online_status_before_restart && !$apache_online_status_after_restart) {
$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);
copy($vhost_file,$vhost_file.'.err');
if(is_file($vhost_file.'~')) {
//* Copy back the last backup file
copy($vhost_file.'~',$vhost_file);
} else {
//* There is no backup file, so we create a empty vhost file with a warning message inside
file_put_contents($vhost_file,"# Apache did not start after modifying this vhost file.\n# Please check file $vhost_file.err for syntax errors.");
}
$app->services->restartService('httpd','restart');
}
} else {
//* We do not check the apache config after changes (is faster)
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
// Remove the backup copy of the config file.
if(@is_file($vhost_file.'~')) unlink($vhost_file.'~');
//* Unset action to clean it for next processed vhost.
$this->action = '';
function delete($event_name,$data) {
global $app, $conf;
// load the server configuration options
$app->uses('getconf');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
tbrehm
committed
//* Check if this is a chrooted setup
if($web_config['website_basedir'] != '' && @is_file($web_config['website_basedir'].'/etc/passwd')) {
tbrehm
committed
$apache_chrooted = true;
} else {
$apache_chrooted = false;
}
if($data['old']['type'] != 'vhost' && $data['old']['parent_domain_id'] > 0) {
//* This is a alias domain or subdomain, so we have to update the website instead
$parent_domain_id = intval($data['old']['parent_domain_id']);
$tmp = $app->db->queryOneRecord('SELECT * FROM web_domain WHERE domain_id = '.$parent_domain_id." AND active = 'y'");
$data['new'] = $tmp;
$data['old'] = $tmp;
$this->action = 'update';
// just run the update function
$this->update($event_name,$data);
} else {
//* This is a website
// Deleting the vhost file, symlink and the data directory
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/'.$data['old']['domain'].'.vhost');
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/900-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
$vhost_symlink = escapeshellcmd($web_config['vhost_conf_enabled_dir'].'/100-'.$data['old']['domain'].'.vhost');
if(is_link($vhost_symlink)){
unlink($vhost_symlink);
$app->log('Removing symlink: '.$vhost_symlink.'->'.$vhost_file,LOGLEVEL_DEBUG);
}
unlink($vhost_file);
$app->log('Removing vhost file: '.$vhost_file,LOGLEVEL_DEBUG);
$docroot = escapeshellcmd($data['old']['document_root']);
if($docroot != '' && !stristr($docroot,'..')) exec('rm -rf '.$docroot);
//remove the php fastgi starter script if available
if ($data['old']['php'] == 'fast-cgi') {
$fastcgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['fastcgi_starter_path']);
exec('rm -rf '.$fastcgi_starter_path);
// remove PHP-FPM pool
if ($data['old']['php'] == 'php-fpm') {
$this->php_fpm_pool_delete($data,$web_config);
}
//remove the php cgi starter script if available
if ($data['old']['php'] == 'cgi') {
// TODO: fetch the date from the server-settings
$web_config['cgi_starter_path'] = $web_config['website_basedir'].'/php-cgi-scripts/[system_user]/';
$cgi_starter_path = str_replace('[system_user]',$data['old']['system_user'],$web_config['cgi_starter_path']);
exec('rm -rf '.$cgi_starter_path);
}
}
$app->log('Removing website: '.$docroot,LOGLEVEL_DEBUG);
// Delete the symlinks for the sites
$client = $app->db->queryOneRecord('SELECT client_id FROM sys_group WHERE sys_group.groupid = '.intval($data['old']['sys_groupid']));
$client_id = intval($client['client_id']);
unset($client);
$tmp_symlinks_array = explode(':',$web_config['website_symlinks']);
if(is_array($tmp_symlinks_array)) {
foreach($tmp_symlinks_array as $tmp_symlink) {
$tmp_symlink = str_replace('[client_id]',$client_id,$tmp_symlink);
$tmp_symlink = str_replace('[website_domain]',$data['old']['domain'],$tmp_symlink);
// Remove trailing slash
if(substr($tmp_symlink, -1, 1) == '/') $tmp_symlink = substr($tmp_symlink, 0, -1);
// create the symlinks, if not exist
if(is_link($tmp_symlink)) {
unlink($tmp_symlink);
$app->log('Removing symlink: '.$tmp_symlink,LOGLEVEL_DEBUG);
}
}
}
// end removing symlinks
// Delete the log file directory
$vhost_logfile_dir = escapeshellcmd('/var/log/ispconfig/httpd/'.$data['old']['domain']);
if($data['old']['domain'] != '' && !stristr($vhost_logfile_dir,'..')) exec('rm -rf '.$vhost_logfile_dir);
$app->log('Removing website logfile directory: '.$vhost_logfile_dir,LOGLEVEL_DEBUG);
//delete the web user
$command = 'userdel';
$command .= ' '.$data['old']['system_user'];
exec($command);
if($apache_chrooted) $this->_exec('chroot '.escapeshellcmd($web_config['website_basedir']).' '.$command);
//* Remove the awstats configuration file
if($data['old']['stats_type'] == 'awstats') {
$this->awstats_delete($data,$web_config);
}
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
//* This function is called when a IP on the server is inserted, updated or deleted
function server_ip($event_name,$data) {
global $app, $conf;
// load the server configuration options
$app->uses('getconf');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
$app->load('tpl');
$tpl = new tpl();
$tpl->newTemplate('apache_ispconfig.conf.master');
$records = $app->db->queryAllRecords('SELECT * FROM server_ip WHERE server_id = '.$conf['server_id']." AND virtualhost = 'y'");
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
$records_out= array();
if(is_array($records)) {
foreach($records as $rec) {
if($rec['ip_type'] == 'IPv6') {
$ip_address = '['.$rec['ip_address'].']';
} else {
$ip_address = $rec['ip_address'];
}
$ports = explode(',',$rec['virtualhost_port']);
if(is_array($ports)) {
foreach($ports as $port) {
$port = intval($port);
if($port > 0 && $port < 65536 && $ip_address != '') {
$records_out[] = array('ip_address' => $ip_address, 'port' => $port);
}
}
}
}
}
if(count($records_out) > 0) {
$tpl->setLoop('ip_adresses',$records_out);
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'].'/ispconfig.conf');
file_put_contents($vhost_file,$tpl->grab());
$app->log('Writing the conf file: '.$vhost_file,LOGLEVEL_DEBUG);
unset($tpl);
}
//* Create or update the .htaccess folder protection
function web_folder_user($event_name,$data) {
global $app, $conf;
$app->uses('system');
if($event_name == 'web_folder_user_delete') {
$folder_id = $data['old']['web_folder_id'];
} else {
$folder_id = $data['new']['web_folder_id'];
}
$folder = $app->db->queryOneRecord("SELECT * FROM web_folder WHERE web_folder_id = ".intval($folder_id));
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
if(!is_array($folder) or !is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
$folder_path = escapeshellcmd($website['document_root'].'/web/'.$folder['path']);
if(substr($folder_path,-1) != '/') $folder_path .= '/';
//* Check if the resulting path is inside the docroot
if(stristr($folder_path,'..') || stristr($folder_path,'./') || stristr($folder_path,'\\')) {
$app->log('Folder path "'.$folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
//* Create the folder path, if it does not exist
if(!is_dir($folder_path)) {
exec('mkdir -p '.$folder_path);
chown($folder_path,$website['system_user']);
chgrp($folder_path,$website['system_group']);
}
//* Create empty .htpasswd file, if it does not exist
if(!is_file($folder_path.'.htpasswd')) {
touch($folder_path.'.htpasswd');
chmod($folder_path.'.htpasswd',0755);
chown($folder_path.'.htpasswd',$website['system_user']);
chgrp($folder_path.'.htpasswd',$website['system_group']);
$app->log('Created file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
/*
$auth_users = $app->db->queryAllRecords("SELECT * FROM web_folder_user WHERE active = 'y' AND web_folder_id = ".intval($folder_id));
$htpasswd_content = '';
if(is_array($auth_users) && !empty($auth_users)){
foreach($auth_users as $auth_user){
$htpasswd_content .= $auth_user['username'].':'.$auth_user['password']."\n";
}
$htpasswd_content = trim($htpasswd_content);
@file_put_contents($folder_path.'.htpasswd', $htpasswd_content);
$app->log('Changed .htpasswd file: '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
*/
if(($data['new']['username'] != $data['old']['username'] || $data['new']['active'] == 'n') && $data['old']['username'] != '') {
$app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
$app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
}
//* Add or remove the user from .htpasswd file
if($event_name == 'web_folder_user_delete') {
$app->system->removeLine($folder_path.'.htpasswd',$data['old']['username'].':');
$app->log('Removed user: '.$data['old']['username'],LOGLEVEL_DEBUG);
if($data['new']['active'] == 'y') {
$app->system->replaceLine($folder_path.'.htpasswd',$data['new']['username'].':',$data['new']['username'].':'.$data['new']['password'],0,1);
$app->log('Added or updated user: '.$data['new']['username'],LOGLEVEL_DEBUG);
}
//if(!is_file($folder_path.'.htaccess')) {
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$folder_path.".htpasswd\nrequire valid-user";
file_put_contents($folder_path.'.htaccess',$ht_file);
chmod($folder_path.'.htaccess',0755);
chown($folder_path.'.htaccess',$website['system_user']);
chgrp($folder_path.'.htaccess',$website['system_group']);
$app->log('Created file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
//}
}
//* Remove .htaccess and .htpasswd file, when folder protection is removed
function web_folder_delete($event_name,$data) {
global $app, $conf;
$folder_id = $data['old']['web_folder_id'];
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($folder['parent_domain_id']));
if(!is_array($folder) or !is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($folder['path'],0,1) == '/') $folder['path'] = substr($folder['path'],1);
if(substr($folder['path'],-1) == '/') $folder['path'] = substr($folder['path'],0,-1);
$folder_path = realpath($website['document_root'].'/web/'.$folder['path']);
if(substr($folder_path,-1) != '/') $folder_path .= '/';
//* Check if the resulting path is inside the docroot
if(substr($folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('Folder path is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
//* Remove .htpasswd file
if(is_file($folder_path.'.htpasswd')) {
unlink($folder_path.'.htpasswd');
$app->log('Removed file '.$folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
//* Remove .htaccess file
if(is_file($folder_path.'.htaccess')) {
unlink($folder_path.'.htaccess');
$app->log('Removed file '.$folder_path.'.htaccess',LOGLEVEL_DEBUG);
}
//* Update folder protection, when path has been changed
function web_folder_update($event_name,$data) {
global $app, $conf;
$website = $app->db->queryOneRecord("SELECT * FROM web_domain WHERE domain_id = ".intval($data['new']['parent_domain_id']));
if(!is_array($website)) {
$app->log('Not able to retrieve folder or website record.',LOGLEVEL_DEBUG);
return false;
}
//* Get the folder path.
if(substr($data['old']['path'],0,1) == '/') $data['old']['path'] = substr($data['old']['path'],1);
if(substr($data['old']['path'],-1) == '/') $data['old']['path'] = substr($data['old']['path'],0,-1);
$old_folder_path = realpath($website['document_root'].'/web/'.$data['old']['path']);
if(substr($old_folder_path,-1) != '/') $old_folder_path .= '/';
if(substr($data['new']['path'],0,1) == '/') $data['new']['path'] = substr($data['new']['path'],1);
if(substr($data['new']['path'],-1) == '/') $data['new']['path'] = substr($data['new']['path'],0,-1);
$new_folder_path = escapeshellcmd($website['document_root'].'/web/'.$data['new']['path']);
if(substr($new_folder_path,-1) != '/') $new_folder_path .= '/';
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
//* Check if the resulting path is inside the docroot
if(stristr($new_folder_path,'..') || stristr($new_folder_path,'./') || stristr($new_folder_path,'\\')) {
$app->log('Folder path "'.$new_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
if(stristr($old_folder_path,'..') || stristr($old_folder_path,'./') || stristr($old_folder_path,'\\')) {
$app->log('Folder path "'.$old_folder_path.'" contains .. or ./.',LOGLEVEL_DEBUG);
return false;
}
//* Check if the resulting path is inside the docroot
if(substr($old_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('Old folder path '.$old_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
if(substr($new_folder_path,0,strlen($website['document_root'])) != $website['document_root']) {
$app->log('New folder path '.$new_folder_path.' is outside of docroot.',LOGLEVEL_DEBUG);
return false;
}
//* Create the folder path, if it does not exist
if(!is_dir($new_folder_path)) exec('mkdir -p '.$new_folder_path);
if($data['old']['path'] != $data['new']['path']) {
//* move .htpasswd file
if(is_file($old_folder_path.'.htpasswd')) {
rename($old_folder_path.'.htpasswd',$new_folder_path.'.htpasswd');
$app->log('Moved file '.$old_folder_path.'.htpasswd to '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
//* delete old .htaccess file
unlink($old_folder_path.'.htaccess');
$app->log('Deleted file '.$old_folder_path.'.htaccess',LOGLEVEL_DEBUG);
}
}
//* Create the .htaccess file
if($data['new']['active'] == 'y') {
$ht_file = "AuthType Basic\nAuthName \"Members Only\"\nAuthUserFile ".$new_folder_path.".htpasswd\nrequire valid-user";
file_put_contents($new_folder_path.'.htaccess',$ht_file);
chmod($new_folder_path.'.htpasswd',0755);
chown($folder_path.'.htpasswd',$website['system_user']);
chgrp($folder_path.'.htpasswd',$website['system_group']);
$app->log('Created file '.$new_folder_path.'.htpasswd',LOGLEVEL_DEBUG);
}
//* Remove .htaccess file
if($data['new']['active'] == 'n' && is_file($new_folder_path.'.htaccess')) {
unlink($new_folder_path.'.htaccess');
$app->log('Removed file '.$new_folder_path.'.htaccess',LOGLEVEL_DEBUG);
/**
* This function is called when a Webdav-User is inserted, updated or deleted.
*
* @author Oliver Vogel
* @param string $event_name
* @param array $data
*/
public function webdav($event_name,$data) {
global $app, $conf;
/*
* load the server configuration options
*/
$app->uses('getconf');
$web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
if (($event_name == 'webdav_user_insert') || ($event_name == 'webdav_user_update')) {
/*
* Get additional informations
*/
$sitedata = $app->db->queryOneRecord('SELECT document_root, domain, system_user, system_group FROM web_domain WHERE domain_id = ' . $data['new']['parent_domain_id']);
$documentRoot = $sitedata['document_root'];
$domain = $sitedata['domain'];
$user = $sitedata['system_user'];
$group = $sitedata['system_group'];
$webdav_user_dir = $documentRoot . '/webdav/' . $data['new']['dir'];
/* 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;
}
//* We dont want to have relative paths here
if(stristr($webdav_user_dir,'..') || stristr($webdav_user_dir,'./')) {
$app->log('Folder path '.$webdav_user_dir.' contains ./ or .. '.$documentRoot,LOGLEVEL_WARN);
return false;
}
//* Check if the resulting path exists if yes, if it is inside the docroot
if(is_dir($webdav_user_dir) && substr(realpath($webdav_user_dir),0,strlen($documentRoot)) != $documentRoot) {
$app->log('Folder path '.$webdav_user_dir.' is outside of docroot '.$documentRoot,LOGLEVEL_WARN);
return false;
}
/*
* First the webdav-root - folder has to exist
*/
if(!is_dir($webdav_user_dir)) {
$app->log('Webdav User directory '.$webdav_user_dir.' does not exist. Creating it now.',LOGLEVEL_DEBUG);
exec('mkdir -p '.escapeshellcmd($webdav_user_dir));
* The webdav - Root needs the group/user as owner and the apache as read and write
$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($documentRoot . '/webdav/'));
$this->_exec('chmod 770 ' . escapeshellcmd($documentRoot . '/webdav/'));
* The webdav folder (not the webdav-root!) needs the same (not in ONE step, because the
* pwd-files are owned by root)
$this->_exec('chown ' . $user . ':' . $group . ' ' . escapeshellcmd($webdav_user_dir.' -R'));
$this->_exec('chmod 770 ' . escapeshellcmd($webdav_user_dir.' -R'));
/*
* if the user is active, we have to write/update the password - file
* if the user is inactive, we have to inactivate the user by removing the user from the file
*/
if ($data['new']['active'] == 'y') {
$this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], $data['new']['password']);
}
else {
/* empty pwd removes the user! */
$this->_writeHtDigestFile( $webdav_user_dir . '.htdigest', $data['new']['username'], $data['new']['dir'], '');
/*
* Next step, patch the vhost - file
*/
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
$this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
/*
* Last, restart apache
*/
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
if ($event_name == 'webdav_user_delete') {
/*
* Get additional informations
*/
$sitedata = $app->db->queryOneRecord('SELECT document_root, domain FROM web_domain WHERE domain_id = ' . $data['old']['parent_domain_id']);
$documentRoot = $sitedata['document_root'];
/*
* We dont't want to destroy any (transfer)-Data. So we do NOT delete any dir.
* So the only thing, we have to do, is to delete the user from the password-file
$this->_writeHtDigestFile( $documentRoot . '/webdav/' . $data['old']['dir'] . '.htdigest', $data['old']['username'], $data['old']['dir'], '');
/*
* Next step, patch the vhost - file
*/
$vhost_file = escapeshellcmd($web_config['vhost_conf_dir'] . '/' . $domain . '.vhost');
$this->_patchVhostWebdav($vhost_file, $documentRoot . '/webdav');
/*
* Last, restart apache
*/
if($apache_chrooted) {
$app->services->restartServiceDelayed('httpd','restart');
} else {
// request a httpd reload when all records have been processed
$app->services->restartServiceDelayed('httpd','reload');
}
}
}
/**
* This function writes the htdigest - files used by webdav and digest
* more info: see http://riceball.com/d/node/424
* @author Oliver Vogel
* @param string $filename The name of the digest-file
* @param string $username The name of the webdav-user
* @param string $authname The name of the realm
* @param string $pwd The password-hash of the user
private function _writeHtDigestFile($filename, $username, $authname, $pwdhash ) {
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
if(is_file($filename)) {
$in = fopen($filename, 'r');
$output = '';
/*
* read line by line and search for the username and authname
*/
while (preg_match("/:/", $line = fgets($in))) {
$line = rtrim($line);
$tmp = explode(':', $line);
if ($tmp[0] == $username && $tmp[1] == $authname) {
/*
* found the user. delete or change it?
*/
if ($pwdhash != '') {
$output .= $tmp[0] . ':' . $tmp[1] . ':' . $pwdhash . "\n";
}
$changed = true;
}
else {
$output .= $line . "\n";
}
fclose($in);
}
/*
* if we didn't change anything, we have to add the new user at the end of the file
*/
if (!$changed) {
$output .= $username . ':' . $authname . ':' . $pwdhash . "\n";
/*
* Now lets write the new file
*/
if(trim($output) == '') {
unlink($filename);
} else {
file_put_contents($filename, $output);
}
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
}
/**
* This function patches the vhost-file and adds all webdav - user.
* This function is written, because the creation of the vhost - file is sophisticated and
* i don't want to make it more "heavy" by also adding this code too...
* @author Oliver Vogel
* @param string $fileName The Name of the .vhost-File (path included)
* @param string $webdavRoot The root of the webdav-folder
*/
private function _patchVhostWebdav($fileName, $webdavRoot) {
$in = fopen($fileName, 'r');
$output = '';
$inWebdavSection = false;
/*
* read line by line and search for the username and authname
*/
while ($line = fgets($in)) {
/*
* is the "replace-comment" found...
*/
if (trim($line) == '# WEBDAV BEGIN') {
/*
* The begin of the webdav - section is found, so ignore all lines til the end is found
*/
$inWebdavSection = true;
$output .= " # WEBDAV BEGIN\n";
/*
* add all the webdav-dirs to the webdav-section
*/
tbrehm
committed
$files = @scandir($webdavRoot);
if(is_array($files)) {
foreach($files as $file) {
if (substr($file, strlen($file) - strlen('.htdigest')) == '.htdigest') {
/*
* found a htdigest - file, so add it to webdav
*/
$fn = substr($file, 0, strlen($file) - strlen('.htdigest'));
$output .= "\n";
// $output .= " Alias /" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
// $output .= " <Location /" . $fn . ">\n";
$output .= " Alias /webdav/" . $fn . ' ' . $webdavRoot . '/' . $fn . "\n";
$output .= " <Location /webdav/" . $fn . ">\n";
$output .= ' BrowserMatch "MSIE" AuthDigestEnableQueryStringHack=On'."\n";
$output .= " AuthType Digest\n";
$output .= " AuthName \"" . $fn . "\"\n";
$output .= " AuthUserFile " . $webdavRoot . '/' . $file . "\n";
$output .= " Require valid-user \n";
$output .= " Options +Indexes \n";
$output .= " Order allow,deny \n";
$output .= " Allow from all \n";
$output .= " </Location> \n";
}
}
tbrehm
committed
}
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
}
/*
* is the "replace-comment-end" found...
*/
if (trim($line) == '# WEBDAV END') {
/*
* The end of the webdav - section is found, so stop ignoring
*/
$inWebdavSection = false;
}
/*
* Write the line to the output, if it is not in the section
*/
if (!$inWebdavSection) {
$output .= $line;
}
}
fclose($in);
/*
* Now lets write the new file
*/
file_put_contents($fileName, $output);
}
//* Update the awstats configuration file
private function awstats_update ($data,$web_config) {
global $app;
$awstats_conf_dir = $web_config['awstats_conf_dir'];
if(!is_dir($data['new']['document_root']."/web/stats/")) mkdir($data['new']['document_root']."/web/stats");
if(!@is_file($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf') || ($data['old']['domain'] != '' && $data['new']['domain'] != $data['old']['domain'])) {
if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
$content .= "Include \"".$awstats_conf_dir."/awstats.conf\"\n";
$content .= "LogFile=\"/var/log/ispconfig/httpd/".$data['new']['domain']."/access.log\"\n";
$content .= "SiteDomain=\"".$data['new']['domain']."\"\n";
$content .= "HostAliases=\"www.".$data['new']['domain']." localhost 127.0.0.1\"\n";
file_put_contents($awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',$content);
$app->log('Created AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['new']['domain'].'.conf',LOGLEVEL_DEBUG);
if(is_file($data['new']['document_root']."/web/stats/index.html")) unlink($data['new']['document_root']."/web/stats/index.html");
copy("/usr/local/ispconfig/server/conf/awstats_index.php.master",$data['new']['document_root']."/web/stats/index.php");
}
//* Delete the awstats configuration file
private function awstats_delete ($data,$web_config) {
global $app;
$awstats_conf_dir = $web_config['awstats_conf_dir'];
if ( @is_file($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf') ) {
unlink($awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf');
$app->log('Removed AWStats config file: '.$awstats_conf_dir.'/awstats.'.$data['old']['domain'].'.conf',LOGLEVEL_DEBUG);
//* Update the PHP-FPM pool configuration file
private function php_fpm_pool_update ($data,$web_config,$pool_dir,$pool_name,$socket_dir) {
global $app, $conf;
//$reload = false;
if($data['new']['php'] == 'php-fpm'){
if(trim($data['new']['fastcgi_php_version']) != ''){
$default_php_fpm = false;
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']));
if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
} else {
$default_php_fpm = true;
}
if(trim($data['old']['fastcgi_php_version']) != '' && $data['old']['php'] == 'php-fpm'){
$default_php_fpm = false;
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']));
if(substr($custom_php_fpm_ini_dir,-1) != '/') $custom_php_fpm_ini_dir .= '/';
} else {
$default_php_fpm = true;
}
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
}
$app->uses("getconf");
$web_config = $app->getconf->get_server_config($conf["server_id"], 'web');
if($data['new']['php'] != 'php-fpm'){
if(@is_file($pool_dir.$pool_name.'.conf')){
unlink($pool_dir.$pool_name.'.conf');
//$reload = true;
}
if($data['old']['php'] == 'php-fpm'){
if(!$default_php_fpm){
$app->services->restartService('php-fpm','reload:'.$custom_php_fpm_init_script);
} else {
$app->services->restartService('php-fpm','reload:'.$conf['init_scripts'].'/'.$web_config['php_fpm_init_script']);
}
}
//if($reload == true) $app->services->restartService('php-fpm','reload');
return;
}
$app->load('tpl');
$tpl = new tpl();
$tpl->newTemplate('php_fpm_pool.conf.master');