From a0fd5ab7b5412985324e970573ca22a27b3a94d3 Mon Sep 17 00:00:00 2001
From: tbrehm <t.brehm@ispconfig.org>
Date: Tue, 16 Apr 2013 05:56:06 -0400
Subject: [PATCH] - Merged revisions 3922-3958 from svn stable branch - Added backup size to web backups

---
 server/lib/classes/system.inc.php |  419 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 383 insertions(+), 36 deletions(-)

diff --git a/server/lib/classes/system.inc.php b/server/lib/classes/system.inc.php
index 685d4f2..c958e8b 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,135 @@
 	 * 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
+		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 +822,7 @@
 	  	}
 	}
 	
+	/*
 	function usermod($user, $groups){
 		global $app;
 	  	if($this->is_user($user)){
@@ -692,6 +862,7 @@
 		    return false;
 	  	}
 	}
+	*/
 	
 	/**boot autostart etc
 	 *
@@ -926,7 +1097,7 @@
 	 *
 	 */
 	function network_info(){
-		$dist = $this->server_conf["dist"];
+		$dist = $this->server_conf['dist'];
 	  	ob_start();
 	  	passthru('ifconfig');
 	  	$output = ob_get_contents();
@@ -950,9 +1121,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 +1217,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 +1258,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 +1303,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 +1333,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) {
@@ -1191,13 +1374,15 @@
 		} else {
 			$dir = escapeshellcmd($maildir_path);
 		}
+		
+		if(!is_dir($dir)) mkdir($dir, 0700, true);
 
 		if($user != '' && $user != 'root' && $this->is_user($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 +1390,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);
@@ -1249,6 +1434,168 @@
 		$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; 
+	}
 
 }
 ?>

--
Gitblit v1.9.1