Skip to content

Commit ac78281

Browse files
author
Till Brehm
committed
Merge branch 'stable-3.1' of git.ispconfig.org:ispconfig/ispconfig3 into stable-3.1
2 parents ed8922b + 126290c commit ac78281

File tree

2 files changed

+106
-11
lines changed

2 files changed

+106
-11
lines changed

server/lib/classes/system.inc.php

Lines changed: 96 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -834,23 +834,55 @@ function chmod($file, $mode, $allow_symlink = false) {
834834
}
835835
}
836836

837-
function file_put_contents($filename, $data, $allow_symlink = false) {
837+
function file_put_contents($filename, $data, $allow_symlink = false, $run_as_user = null) {
838838
global $app;
839839
if($allow_symlink == false && $this->checkpath($filename) == false) {
840840
$app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
841841
return false;
842842
}
843-
if(file_exists($filename)) unlink($filename);
844-
return file_put_contents($filename, $data);
843+
if($run_as_user !== null && $run_as_user !== 'root') {
844+
if(!$this->check_run_as_user($run_as_user)) {
845+
$app->log("Action aborted, invalid run-as-user: $run_as_user", LOGLEVEL_WARN);
846+
return false;
847+
}
848+
if(file_exists($filename)) {
849+
$cmd = $this->get_sudo_command('rm ' . escapeshellarg($filename), $run_as_user);
850+
$this->exec_safe($cmd);
851+
}
852+
$cmd = $this->get_sudo_command('cat - > ' . escapeshellarg($filename), $run_as_user);
853+
$retval = null;
854+
$stderr = '';
855+
$this->pipe_exec($cmd, $data, $retval, $stderr);
856+
if($retval > 0) {
857+
$app->log("Safe file_put_contents failed: $stderr", LOGLEVEL_WARN);
858+
return false;
859+
} else {
860+
$size = filesize($filename);
861+
return $size;
862+
}
863+
} else {
864+
if(file_exists($filename)) unlink($filename);
865+
return file_put_contents($filename, $data);
866+
}
845867
}
846868

847-
function file_get_contents($filename, $allow_symlink = false) {
869+
function file_get_contents($filename, $allow_symlink = false, $run_as_user = null) {
848870
global $app;
849871
if($allow_symlink == false && $this->checkpath($filename) == false) {
850872
$app->log("Action aborted, file is a symlink: $filename", LOGLEVEL_WARN);
851873
return false;
852874
}
853-
return file_get_contents($filename, $data);
875+
876+
if($run_as_user !== null && $run_as_user !== 'root') {
877+
if(!$this->check_run_as_user($run_as_user)) {
878+
$app->log("Action aborted, invalid run-as-user: $run_as_user", LOGLEVEL_WARN);
879+
return false;
880+
}
881+
$cmd = $this->get_sudo_command('cat ' . escapeshellarg($filename), $run_as_user) . ' 2>/dev/null';
882+
return $this->system_safe($cmd);
883+
} else {
884+
return file_get_contents($filename);
885+
}
854886
}
855887

856888
function rename($filename, $new_filename, $allow_symlink = false) {
@@ -862,13 +894,29 @@ function rename($filename, $new_filename, $allow_symlink = false) {
862894
return rename($filename, $new_filename);
863895
}
864896

865-
function mkdir($dirname, $allow_symlink = false, $mode = 0777, $recursive = false) {
897+
function mkdir($dirname, $allow_symlink = false, $mode = 0777, $recursive = false, $run_as_user = null) {
866898
global $app;
867899
if($allow_symlink == false && $this->checkpath($dirname) == false) {
868900
$app->log("Action aborted, file is a symlink: $dirname", LOGLEVEL_WARN);
869901
return false;
870902
}
871-
if(@mkdir($dirname, $mode, $recursive)) {
903+
if($run_as_user !== null && !$this->check_run_as_user($run_as_user)) {
904+
$app->log("Action aborted, invalid run-as-user: $run_as_user", LOGLEVEL_WARN);
905+
return false;
906+
}
907+
$success = false;
908+
if($run_as_user !== null && $run_as_user !== 'root') {
909+
$cmd = $this->get_sudo_command('mkdir ' . ($recursive ? '-p ' : '') . escapeshellarg($dirname), $run_as_user) . ' >/dev/null 2>&1';
910+
$this->exec_safe($cmd);
911+
if($this->last_exec_retcode() != 0) {
912+
$success = false;
913+
} else {
914+
$success = true;
915+
}
916+
} else {
917+
$success = @mkdir($dirname, $mode, $recursive);
918+
}
919+
if($success) {
872920
return true;
873921
} else {
874922
$app->log("mkdir failed: $dirname", LOGLEVEL_DEBUG);
@@ -1677,14 +1725,14 @@ function maildirmake($maildir_path, $user = '', $subfolder = '', $group = '') {
16771725
}
16781726

16791727
//* Function to create directory paths and chown them to a user and group
1680-
function mkdirpath($path, $mode = 0755, $user = '', $group = '') {
1728+
function mkdirpath($path, $mode = 0755, $user = '', $group = '', $run_as_user = null) {
16811729
$path_parts = explode('/', $path);
16821730
$new_path = '';
16831731
if(is_array($path_parts)) {
16841732
foreach($path_parts as $part) {
16851733
$new_path .= '/'.$part;
16861734
if(!@is_dir($new_path)) {
1687-
$this->mkdir($new_path);
1735+
$this->mkdir($new_path, false, 0777, false, $run_as_user);
16881736
$this->chmod($new_path, $mode);
16891737
if($user != '') $this->chown($new_path, $user);
16901738
if($group != '') $this->chgrp($new_path, $group);
@@ -2191,4 +2239,43 @@ public function create_jailkit_chroot($home_dir, $app_sections = array()) {
21912239
return true;
21922240
}
21932241

2242+
2243+
public function pipe_exec($cmd, $stdin, &$retval = null, &$stderr = null) {
2244+
$descriptors = array(
2245+
0 => array('pipe', 'r'),
2246+
1 => array('pipe', 'w'),
2247+
2 => array('pipe', 'w')
2248+
);
2249+
2250+
$result = '';
2251+
$pipes = null;
2252+
$proc = proc_open($cmd, $descriptors, $pipes);
2253+
if(is_resource($proc)) {
2254+
fwrite($pipes[0], $stdin);
2255+
fclose($pipes[0]);
2256+
2257+
$result = stream_get_contents($pipes[1]);
2258+
$stderr = stream_get_contents($pipes[2]);
2259+
fclose($pipes[1]);
2260+
fclose($pipes[2]);
2261+
2262+
$retval = proc_close($proc);
2263+
2264+
return $result;
2265+
} else {
2266+
return false;
2267+
}
2268+
}
2269+
2270+
private function get_sudo_command($cmd, $run_as_user) {
2271+
return 'sudo -u ' . escapeshellarg($run_as_user) . ' sh -c ' . escapeshellarg($cmd);
2272+
}
2273+
2274+
private function check_run_as_user($username) {
2275+
if(preg_match('/^[a-zA-Z0-9_\-]+$/', $username)) {
2276+
return true;
2277+
} else{
2278+
return false;
2279+
}
2280+
}
21942281
}

server/plugins-available/shelluser_base_plugin.inc.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,20 @@ function insert($event_name, $data) {
129129
$app->system->chgrp($homedir,$data['new']['pgroup'],false);
130130
}
131131
$command = 'useradd -d ? -g ? -o'; // non unique
132-
if($data['new']['password'] != '') $command .= ' -p ' . escapeshellarg($data['new']['password']);
133132
$command .= ' -s ? -u ? ?';
134133
$app->system->exec_safe($command, $homedir, $data['new']['pgroup'], $data['new']['shell'], $uid, $data['new']['username']);
135134
$app->log("Executed command: ".$command, LOGLEVEL_DEBUG);
136135
$app->log("Added shelluser: ".$data['new']['username'], LOGLEVEL_DEBUG);
137-
136+
137+
if($data['new']['password'] != '') {
138+
$retval = null;
139+
$stderr = '';
140+
$app->system->pipe_exec('chpasswd -e ' . escapeshellarg($data['new']['username']), $data['new']['username'] . ':' . $data['new']['password'], $retval, $stderr);
141+
if($retval != 0) {
142+
$app->log("Command chpasswd failed for user ".$data['new']['username'] . ' with code ' . $retval . ': ' . $stderr, LOGLEVEL_WARN);
143+
}
144+
}
145+
138146
$app->system->chown($data['new']['dir'],$data['new']['username'],false);
139147
$app->system->chgrp($data['new']['dir'],$data['new']['pgroup'],false);
140148

0 commit comments

Comments
 (0)