From 7d52e00a51450bc4a080d4e21b7dda02c0a65191 Mon Sep 17 00:00:00 2001
From: Marius Cramer <m.cramer@pixcept.de>
Date: Thu, 14 Nov 2013 05:42:06 -0500
Subject: [PATCH] Fixed list sorting
---
server/lib/classes/system.inc.php | 451 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 409 insertions(+), 42 deletions(-)
diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index c383423..a1e7c00 100644
--- a/server/lib/classes/system.inc.php
+++ b/server/lib/classes/system.inc.php
@@ -41,9 +41,9 @@
* @return system
*/
public function system(){
- global $go_info;
- $this->server_id = $go_info['isp']['server_id'];
- $this->server_conf = $go_info['isp']['server_conf'];
+ //global $go_info;
+ //$this->server_id = $go_info['isp']['server_id'];
+ //$this->server_conf = $go_info['isp']['server_conf'];
$this->server_conf['passwd_datei'] = '/etc/passwd';
$this->server_conf['shadow_datei'] = '/etc/shadow';
$this->server_conf['group_datei'] = '/etc/group';
@@ -575,6 +575,58 @@
}
/**
+ * Get the group id from an group
+ *
+ */
+ function getgid($group){
+ global $app;
+ if($this->is_group($group)){
+ $group_datei = $this->server_conf['group_datei'];
+ $groups = $app->file->no_comments($group_datei);
+ $lines = explode("\n", $groups);
+ if(is_array($lines)){
+ foreach($lines as $line){
+ if(trim($line) != ""){
+ list($f1, $f2, $f3, $f4) = explode(':', $line);
+ if($f1 == $group) return $f3;
+ }
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Return info about a group by name
+ *
+ */
+ function posix_getgrnam($group) {
+ if(!function_exists('posix_getgrnam')){
+ $group_datei = $this->server_conf['group_datei'];
+ $cmd = 'grep -m 1 "^'.$group.':" '.$group_datei;
+ exec($cmd, $output, $return_var);
+ if($return_var != 0 || !$output[0]) return false;
+ list($f1, $f2, $f3, $f4) = explode(':', $output[0]);
+ $f2 = trim($f2);
+ $f3 = trim($f3);
+ $f4 = trim($f4);
+ if($f4 != ''){
+ $members = explode(',', $f4);
+ } else {
+ $members = array();
+ }
+ $group_details = array( 'name' => $group,
+ 'passwd' => $f2,
+ 'members' => $members,
+ 'gid' => $f3);
+ return $group_details;
+ } else {
+ return posix_getgrnam($group);
+ }
+ }
+
+ /**
* Get all information from a user
*
*/
@@ -610,18 +662,136 @@
* Edit the owner of a file
*
*/
- function chown($file, $owner, $group = ''){
- $owner_change = @chown($file, $owner);
- if($group != ''){
- $group_change = @chgrp($file, $group);
- } else {
- $group_change = 1;
+ function chown($file, $owner, $allow_symlink = false){
+ global $app;
+ if($allow_symlink == false && $this->checkpath($file) == false) {
+ $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+ return false;
}
- if($owner_change && $group_change){
- return true;
- } else {
- return false;
+ if(file_exists($file)) {
+ if(@chown($file, $owner)) {
+ return true;
+ } else {
+ $app->log("chown failed: $file : $owner",LOGLEVEL_DEBUG);
+ return false;
+ }
}
+ }
+
+ function chgrp($file, $group = '', $allow_symlink = false){
+ global $app;
+ if($allow_symlink == false && $this->checkpath($file) == false) {
+ $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+ return false;
+ }
+ if(file_exists($file)) {
+ if(@chgrp($file, $group)) {
+ return true;
+ } else {
+ $app->log("chgrp failed: $file : $group",LOGLEVEL_DEBUG);
+ return false;
+ }
+ }
+ }
+
+ //* Change the mode of a file
+ function chmod($file, $mode, $allow_symlink = false) {
+ global $app;
+ if($allow_symlink == false && $this->checkpath($file) == false) {
+ $app->log("Action aborted, file is a symlink: $file",LOGLEVEL_WARN);
+ return false;
+ }
+ if(@chmod($file, $mode)) {
+ return true;
+ } else {
+ $app->log("chmod failed: $file : $mode",LOGLEVEL_DEBUG);
+ return false;
+ }
+ }
+
+ function file_put_contents($filename, $data, $allow_symlink = false) {
+ global $app;
+ if($allow_symlink == false && $this->checkpath($filename) == false) {
+ $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+ return false;
+ }
+ if(file_exists($filename)) unlink($filename);
+ return file_put_contents($filename, $data);
+ }
+
+ function file_get_contents($filename, $allow_symlink = false) {
+ global $app;
+ if($allow_symlink == false && $this->checkpath($filename) == false) {
+ $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+ return false;
+ }
+ return file_get_contents($filename, $data);
+ }
+
+ function rename($filename, $new_filename, $allow_symlink = false) {
+ global $app;
+ if($allow_symlink == false && $this->checkpath($filename) == false) {
+ $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+ return false;
+ }
+ return rename($filename, $new_filename);
+ }
+
+ function mkdir($dirname, $allow_symlink = false) {
+ global $app;
+ if($allow_symlink == false && $this->checkpath($dirname) == false) {
+ $app->log("Action aborted, file is a symlink: $dirname",LOGLEVEL_WARN);
+ return false;
+ }
+ if(@mkdir($dirname)) {
+ return true;
+ } else {
+ $app->log("mkdir failed: $dirname",LOGLEVEL_DEBUG);
+ return false;
+ }
+ }
+
+ function unlink($filename) {
+ if(file_exists($filename) || is_link($filename)) {
+ return unlink($filename);
+ }
+ }
+
+ function copy($file1,$file2) {
+ return copy($file1,$file2);
+ }
+
+ function touch($file, $allow_symlink = false){
+ global $app;
+ if($allow_symlink == false && @file_exists($file) && $this->checkpath($file) == false) {
+ $this->unlink($file);
+ }
+ if(@touch($file)) {
+ return true;
+ } else {
+ $app->log("touch failed: $file",LOGLEVEL_DEBUG);
+ return false;
+ }
+ }
+
+ function checkpath($path) {
+ $path = trim($path);
+ //* We allow only absolute paths
+ if(substr($path,0,1) != '/') return false;
+
+ //* We allow only some characters in the path
+ // * is allowed, for example it is part of wildcard certificates/keys: *.example.com.crt
+ if(!preg_match('@^/[-a-zA-Z0-9_/.*~]{1,}$@',$path)) return false;
+
+ //* Check path for symlinks
+ $path_parts = explode('/',$path);
+ $testpath = '';
+ foreach($path_parts as $p) {
+ $testpath .= '/'.$p;
+ if(is_link($testpath)) return false;
+ }
+
+ return true;
}
/**
@@ -653,6 +823,7 @@
}
}
+ /*
function usermod($user, $groups){
global $app;
if($this->is_user($user)){
@@ -692,6 +863,7 @@
return false;
}
}
+ */
/**boot autostart etc
*
@@ -926,7 +1098,7 @@
*
*/
function network_info(){
- $dist = $this->server_conf["dist"];
+ $dist = $this->server_conf['dist'];
ob_start();
passthru('ifconfig');
$output = ob_get_contents();
@@ -950,9 +1122,9 @@
}
$output = trim(ob_get_contents());
ob_end_clean();
- if($output != ""){
- $ifconfig["INTERFACE"][$interface] = $output;
- $ifconfig["IP"][$output] = $interface;
+ if($output != ''){
+ $ifconfig['INTERFACE'][$interface] = $output;
+ $ifconfig['IP'][$output] = $interface;
}
}
if(!empty($ifconfig)){
@@ -1046,7 +1218,7 @@
function make_trashscan(){
global $app;
//trashscan erstellen
- // Template �ffnen
+ // Template Öffnen
$app->tpl->clear_all();
$app->tpl->define( array(table => 'trashscan.master'));
@@ -1087,23 +1259,23 @@
if ($urlHandle){
socket_set_timeout($urlHandle, $timeout);
- $urlString = 'GET '.$path." HTTP/1.0\r\nHost: ".$url_parts["host"]."\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
+ $urlString = 'GET '.$path." HTTP/1.0\r\nHost: ".$url_parts['host']."\r\nConnection: Keep-Alive\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\r\n";
if ($user) $urlString .= 'Authorization: Basic '.base64_encode($user.':'.$pass)."\r\n";
$urlString .= "\r\n";
fputs($urlHandle, $urlString);
- $month["Jan"] = '01';
- $month["Feb"] = '02';
- $month["Mar"] = '03';
- $month["Apr"] = '04';
- $month["May"] = '05';
- $month["Jun"] = '06';
- $month["Jul"] = '07';
- $month["Aug"] = '08';
- $month["Sep"] = '09';
- $month["Oct"] = '10';
- $month["Nov"] = '11';
- $month["Dec"] = '12';
+ $month['Jan'] = '01';
+ $month['Feb'] = '02';
+ $month['Mar'] = '03';
+ $month['Apr'] = '04';
+ $month['May'] = '05';
+ $month['Jun'] = '06';
+ $month['Jul'] = '07';
+ $month['Aug'] = '08';
+ $month['Sep'] = '09';
+ $month['Oct'] = '10';
+ $month['Nov'] = '11';
+ $month['Dec'] = '12';
$c = 0;
$l = 0;
$startzeit = time();
@@ -1132,6 +1304,11 @@
}
function replaceLine($filename,$search_pattern,$new_line,$strict = 0,$append = 1) {
+ global $app;
+ if($this->checkpath($filename) == false) {
+ $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+ return false;
+ }
$lines = @file($filename);
$out = '';
$found = 0;
@@ -1157,14 +1334,21 @@
if($found == 0) {
//* add \n if the last line does not end with \n or \r
- if(substr($out,-1) != "\n" && substr($out,-1) != "\r") $out .= "\n";
+ if(substr($out,-1) != "\n" && substr($out,-1) != "\r" && filesize($filename) > 0) $out .= "\n";
//* add the new line at the end of the file
- if($append == 1) $out .= $new_line."\n";
+ if($append == 1) {
+ $out .= $new_line."\n";
+ }
}
file_put_contents($filename,$out);
}
function removeLine($filename,$search_pattern,$strict = 0) {
+ global $app;
+ if($this->checkpath($filename) == false) {
+ $app->log("Action aborted, file is a symlink: $filename",LOGLEVEL_WARN);
+ return false;
+ }
if($lines = @file($filename)) {
$out = '';
foreach($lines as $line) {
@@ -1187,17 +1371,19 @@
global $app;
if($subfolder != '') {
- $dir = escapeshellarg($maildir_path.'/.'.$subfolder);
+ $dir = escapeshellcmd($maildir_path.'/.'.$subfolder);
} else {
- $dir = escapeshellarg($maildir_path);
+ $dir = escapeshellcmd($maildir_path);
}
+
+ if(!is_dir($dir)) mkdir($dir, 0700, true);
if($user != '' && $user != 'root' && $this->is_user($user)) {
- $user = escapeshellarg($user);
+ $user = escapeshellcmd($user);
// I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
$group = $user;
- chown($dir,$user);
- chgrp($dir,$group);
+ if(is_dir($dir)) $this->chown($dir,$user);
+ if(is_dir($dir)) $this->chgrp($dir,$group);
$chown_mdsub = true;
}
@@ -1205,7 +1391,7 @@
$maildirsubs = array('cur','new','tmp');
foreach ($maildirsubs as $mdsub) {
- mkdir($dir.'/'.$mdsub, 0700, true);
+ if(!is_dir($dir.'/'.$mdsub)) mkdir($dir.'/'.$mdsub, 0700, true);
if ($chown_mdsub) {
chown($dir.'/'.$mdsub, $user);
chgrp($dir.'/'.$mdsub, $group);
@@ -1214,18 +1400,20 @@
chmod($dir, 0700);
+ /*
if($user != '' && $this->is_user($user) && $user != 'root') {
- $user = escapeshellarg($user);
+ $user = escapeshellcmd($user);
// I assume that the name of the (vmail group) is the same as the name of the mail user in ISPConfig 3
$group = $user;
exec("chown $user:$group $dir $dir_cur $dir_new $dir_tmp");
}
+ */
//* Add the subfolder to the subscriptions and courierimapsubscribed files
if($subfolder != '') {
// Courier
if(!is_file($maildir_path.'/courierimapsubscribed')) {
- $tmp_file = escapeshellarg($maildir_path.'/courierimapsubscribed');
+ $tmp_file = escapeshellcmd($maildir_path.'/courierimapsubscribed');
touch($tmp_file);
chmod($tmp_file, 0744);
chown($tmp_file,'vmail');
@@ -1235,7 +1423,7 @@
// Dovecot
if(!is_file($maildir_path.'/subscriptions')) {
- $tmp_file = escapeshellarg($maildir_path.'/subscriptions');
+ $tmp_file = escapeshellcmd($maildir_path.'/subscriptions');
touch($tmp_file);
chmod($tmp_file, 0744);
chown($tmp_file,'vmail');
@@ -1247,6 +1435,185 @@
$app->log('Created Maildir '.$maildir_path.' with subfolder: '.$subfolder,LOGLEVEL_DEBUG);
}
+
+ //* Function to create directory paths and chown them to a user and group
+ function mkdirpath($path, $mode = 0755, $user = '', $group = '') {
+ $path_parts = explode('/',$path);
+ $new_path = '';
+ if(is_array($path_parts)) {
+ foreach($path_parts as $part) {
+ $new_path .= '/'.$part;
+ if(!@is_dir($new_path)) {
+ $this->mkdir($new_path);
+ $this->chmod($new_path,$mode);
+ if($user != '') $this->chown($new_path,$user);
+ if($group != '') $this->chgrp($new_path,$group);
+ }
+ }
+ }
+
+ }
+
+ //* Check if a application is installed
+ function is_installed($appname) {
+ exec('which '.escapeshellcmd($appname).' 2> /dev/null',$out,$returncode);
+ if(isset($out[0]) && stristr($out[0],$appname) && $returncode == 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ function web_folder_protection($document_root,$protect) {
+ global $app,$conf;
+
+ if($this->checkpath($document_root) == false) {
+ $app->log("Action aborted, target is a symlink: $document_root",LOGLEVEL_DEBUG);
+ return false;
+ }
+
+ //* load the server configuration options
+ $app->uses('getconf');
+ $web_config = $app->getconf->get_server_config($conf['server_id'], 'web');
+
+ if($protect == true && $web_config['web_folder_protection'] == 'y') {
+ //* Add protection
+ if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr +i '.escapeshellcmd($document_root));
+ } else {
+ //* Remove protection
+ if($document_root != '' && $document_root != '/' && strlen($document_root) > 6 && !stristr($document_root,'..')) exec('chattr -i '.escapeshellcmd($document_root));
+ }
+ }
+
+ function usermod($username, $uid = 0, $gid = 0, $home = '', $shell = '', $password = '', $login = '') {
+ global $app;
+
+ if($login == '') $login = $username;
+
+ //* Change values in /etc/passwd
+ $passwd_file_array = file('/etc/passwd');
+ if(is_array($passwd_file_array)) {
+ foreach($passwd_file_array as $line) {
+ $line = trim($line);
+ $parts = explode(':',$line);
+ if($parts[0] == $username) {
+ if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
+ if(!empty($uid)) $parts[2] = trim($uid);
+ if(!empty($gid)) $parts[3] = trim($gid);
+ if(trim($home) != '') $parts[5] = trim($home);
+ if(trim($shell) != '') $parts[6] = trim($shell);
+ $new_line = implode(':',$parts);
+ copy('/etc/passwd','/etc/passwd~');
+ chmod('/etc/passwd~',0600);
+ $app->uses('system');
+ $app->system->replaceLine('/etc/passwd',$line,$new_line,1,0);
+ }
+ }
+ unset($passwd_file_array);
+ }
+
+ //* If username != login, change username in group and gshadow file
+ if($username != $login) {
+ $group_file_array = file('/etc/group');
+ if(is_array($group_file_array)) {
+ foreach($group_file_array as $line) {
+ $line = trim($line);
+ $parts = explode(':',$line);
+ if(strstr($parts[3],$username)) {
+ $uparts = explode(',',$parts[3]);
+ if(is_array($uparts)) {
+ foreach($uparts as $key => $val) {
+ if($val == $username) $uparts[$key] = $login;
+ }
+ }
+ $parts[3] = implode(',',$uparts);
+ $new_line = implode(':',$parts);
+ copy('/etc/group','/etc/group~');
+ chmod('/etc/group~',0600);
+ $app->system->replaceLine('/etc/group',$line,$new_line,1,0);
+ }
+ }
+ }
+ unset($group_file_array);
+
+ $gshadow_file_array = file('/etc/gshadow');
+ if(is_array($gshadow_file_array)) {
+ foreach($gshadow_file_array as $line) {
+ $line = trim($line);
+ $parts = explode(':',$line);
+ if(strstr($parts[3],$username)) {
+ $uparts = explode(',',$parts[3]);
+ if(is_array($uparts)) {
+ foreach($uparts as $key => $val) {
+ if($val == $username) $uparts[$key] = $login;
+ }
+ }
+ $parts[3] = implode(',',$uparts);
+ $new_line = implode(':',$parts);
+ copy('/etc/gshadow','/etc/gshadow~');
+ chmod('/etc/gshadow~',0600);
+ $app->system->replaceLine('/etc/gshadow',$line,$new_line,1,0);
+ }
+ }
+ }
+ unset($group_file_array);
+ }
+
+
+ //* When password or login name has been changed
+ if($password != '' || $username != $login) {
+ $shadow_file_array = file('/etc/shadow');
+ if(is_array($shadow_file_array)) {
+ foreach($shadow_file_array as $line) {
+ $line = trim($line);
+ $parts = explode(':',$line);
+ if($parts[0] == $username) {
+ if(trim($login) != '' && trim($login) != trim($username)) $parts[0] = trim($login);
+ if(trim($password) != '') $parts[1] = trim($password);
+ $new_line = implode(':',$parts);
+ copy('/etc/shadow','/etc/shadow~');
+ chmod('/etc/shadow~',0600);
+ $app->system->replaceLine('/etc/shadow',$line,$new_line,1,0);
+ }
+ }
+ }
+ unset($shadow_file_array);
+ }
+ }
+
+ function intval($string, $force_numeric = false) {
+ if(intval($string) == 2147483647) {
+ if($force_numeric == true) return floatval($string);
+ elseif(preg_match('/^([-]?)[0]*([1-9][0-9]*)([^0-9].*)*$/', $string, $match)) return $match[1].$match[2];
+ else return 0;
+ } else {
+ return intval($string);
+ }
+ }
+
+ function is_mounted($mountpoint){
+ //$cmd = 'df 2>/dev/null | grep " '.$mountpoint.'$"';
+ $cmd = 'mount 2>/dev/null | grep " on '.$mountpoint.' type "';
+ exec($cmd, $output, $return_var);
+ return $return_var == 0 ? true : false;
+ }
+
+ function getinitcommand($servicename, $action, $init_script_directory = ''){
+ global $conf;
+ // systemd
+ if(is_executable('/bin/systemd')){
+ return 'systemctl '.$action.' '.$servicename.'.service';
+ }
+ // upstart
+ if(is_executable('/sbin/initctl')){
+ exec('/sbin/initctl version 2>/dev/null | /bin/grep -q upstart', $retval['output'], $retval['retval']);
+ if(intval($retval['retval']) == 0) return 'service '.$servicename.' '.$action;
+ }
+ // sysvinit
+ if($init_script_directory == '') $init_script_directory = $conf['init_scripts'];
+ if(substr($init_script_directory, -1) === '/') $init_script_directory = substr($init_script_directory, 0, -1);
+ return $init_script_directory.'/'.$servicename.' '.$action;
+ }
}
?>
--
Gitblit v1.9.1