Skip to content

Commit ee79725

Browse files
committed
jailkit updating bugfixes
1 parent 0f71181 commit ee79725

File tree

5 files changed

+117
-67
lines changed

5 files changed

+117
-67
lines changed

server/lib/classes/cron.d/600-jailkit_maintenance.inc.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,15 @@ public function onRunJob() {
6161
print "Migration mode active, not running Jailkit updates.\n";
6262
}
6363

64-
$update_options = array( 'allow_hardlink', );
65-
6664
$jailkit_config = $app->getconf->get_server_config($conf['server_id'], 'jailkit');
6765
if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
6866
if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
6967
$update_options = array( 'hardlink', );
7068
} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
71-
unset($update_options['allow_hardlink']);
69+
$update_optiosn = array();
7270
}
71+
} else {
72+
$update_options = array( 'allow_hardlink', );
7373
}
7474

7575
// limit the number of jails we update at one time according to time of day

server/lib/classes/functions.inc.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,26 @@ public function array_merge($array1, $array2) {
118118
return $out;
119119
}
120120

121+
public function array_unset_by_value($array, $value) {
122+
if (!is_array($array)) {
123+
return $array;
124+
}
125+
if (is_array($value)) {
126+
foreach ($array as $key => $val){
127+
if (in_array($val, $value)) {
128+
unset($array[$key]);
129+
}
130+
}
131+
} else {
132+
foreach ($array as $key => $val){
133+
if ($val == $value) {
134+
unset($array[$key]);
135+
}
136+
}
137+
}
138+
return $array;
139+
}
140+
121141
public function currency_format($number, $view = '') {
122142
global $app;
123143
if($view != '') $number_format_decimals = (int)$app->lng('number_format_decimals_'.$view);

server/lib/classes/system.inc.php

Lines changed: 61 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -949,15 +949,17 @@ function rmdir($path, $recursive=false) {
949949
}
950950

951951
$path = rtrim($path, '/');
952-
if (is_dir($path)) {
952+
if (is_dir($path) && !is_link($path)) {
953953
$objects = array_diff(scandir($path), array('.', '..'));
954954
foreach ($objects as $object) {
955955
if ($recursive) {
956-
if (is_dir("$path/$object")) {
956+
if (is_dir("$path/$object") && !is_link("$path/$object")) {
957957
$this->rmdir("$path/$object", $recursive);
958958
} else {
959959
unlink ("$path/$object");
960960
}
961+
} else {
962+
$app->log("rmdir: invoked non-recursive, not removing $path (expect rmdir failure)", LOGLEVEL_DEBUG);
961963
}
962964
}
963965
return rmdir($path);
@@ -1011,16 +1013,18 @@ function remove_broken_symlinks($path, $recursive=false) {
10111013
if ($path != '/') {
10121014
$path = rtrim($path, '/');
10131015
}
1016+
global $app;
1017+
#$app->log("remove_broken_symlinks: checking path: $path", LOGLEVEL_DEBUG);
10141018
if (is_dir($path)) {
1019+
#$app->log("remove_broken_symlinks: $path is dir, running scandir", LOGLEVEL_DEBUG);
10151020
$objects = array_diff(scandir($path), array('.', '..'));
10161021
foreach ($objects as $object) {
1017-
if ($recursive) {
1018-
if (is_dir("$path/$object")) {
1019-
$this->remove_broken_symlinks("$path/$object", $recursive);
1020-
} elseif (is_link("$path/$object") && !file_exists("$path/$object")) {
1022+
#$app->log("remove_broken_symlinks: scandir found $object", LOGLEVEL_DEBUG);
1023+
if (is_dir("$path/$object") && $recursive) {
1024+
$this->remove_broken_symlinks("$path/$object", $recursive);
1025+
} elseif (is_link("$path/$object") && !file_exists("$path/$object")) {
10211026
$app->log("removing broken symlink $path/$object", LOGLEVEL_DEBUG);
1022-
unlink ("$path/$object");
1023-
}
1027+
unlink ("$path/$object");
10241028
}
10251029
}
10261030
} elseif (is_link("$path") && !file_exists("$path")) {
@@ -2299,10 +2303,12 @@ public function create_jailkit_chroot($home_dir, $app_sections = array(), $optio
22992303
$program_args = '';
23002304
foreach ($options as $opt) {
23012305
switch ($opt) {
2302-
case '-k|hardlink':
2306+
case '-k':
2307+
case 'hardlink':
23032308
$program_args .= ' -k';
23042309
break;
2305-
case '-f|force':
2310+
case '-f':
2311+
case 'force':
23062312
$program_args .= ' -f';
23072313
break;
23082314
}
@@ -2365,10 +2371,12 @@ public function create_jailkit_programs($home_dir, $programs = array(), $options
23652371
$program_args = '';
23662372
foreach ($options as $opt) {
23672373
switch ($opt) {
2368-
case '-k|hardlink':
2374+
case '-k':
2375+
case 'hardlink':
23692376
$program_args .= ' -k';
23702377
break;
2371-
case '-f|force':
2378+
case '-f':
2379+
case 'force':
23722380
$program_args .= ' -f';
23732381
break;
23742382
}
@@ -2400,6 +2408,7 @@ public function create_jailkit_programs($home_dir, $programs = array(), $options
24002408
public function update_jailkit_chroot($home_dir, $sections = array(), $programs = array(), $options = array()) {
24012409
global $app;
24022410

2411+
$app->log("update_jailkit_chroot called for $home_dir with options ".print_r($options, true), LOGLEVEL_DEBUG);
24032412
$app->uses('ini_parser');
24042413

24052414
// Disallow operating on root directory
@@ -2416,10 +2425,12 @@ public function update_jailkit_chroot($home_dir, $sections = array(), $programs
24162425
$opts = array();
24172426
foreach ($options as $opt) {
24182427
switch ($opt) {
2419-
case '-k|hardlink':
2428+
case '-k':
2429+
case 'hardlink':
24202430
$opts[] = 'hardlink';
24212431
break;
2422-
case '-f|force':
2432+
case '-f':
2433+
case 'force':
24232434
$opts[] = 'force';
24242435
break;
24252436
}
@@ -2460,57 +2471,66 @@ public function update_jailkit_chroot($home_dir, $sections = array(), $programs
24602471
continue;
24612472
}
24622473

2463-
$this->remove_broken_symlinks($dir, true);
2474+
$this->remove_broken_symlinks($jail_dir, true);
24642475

24652476
// save list of hardlinked files
2466-
if (!in_array('hardlink', $opts) && !in_array('allow_hardlink', $options)) {
2477+
if (!(in_array('hardlink', $opts) || in_array('allow_hardlink', $options))) {
2478+
$app->log("update_jailkit_chroot: searching for hardlinks in $jail_dir", LOGLEVEL_DEBUG);
24672479
$find_multiple_links = function ( $path ) use ( &$find_multiple_links ) {
24682480
$found = array();
2469-
if (is_dir($path)) {
2481+
if (is_dir($path) && !is_link($path)) {
24702482
$objects = array_diff(scandir($path), array('.', '..'));
24712483
foreach ($objects as $object) {
24722484
$ret = $find_multiple_links( "$path/$object" );
24732485
if (count($ret) > 0) {
24742486
$found = array_merge($found, $ret);
24752487
}
24762488
}
2477-
} else {
2478-
$stat = stat($path);
2489+
} elseif (is_file($path)) {
2490+
$stat = lstat($path);
24792491
if ($stat['nlink'] > 1) {
24802492
$found[$path] = $path;
24812493
}
24822494
}
24832495
return $found;
24842496
};
24852497

2486-
$ret = $find_multiple_links( $jail_dir );
2498+
$ret = $find_multiple_links($jail_dir);
24872499
if (count($ret) > 0) {
24882500
$multiple_links = array_merge($multiple_links, $ret);
24892501
}
2490-
}
24912502

2492-
// remove broken symlinks a second time after hardlink cleanup
2493-
$this->remove_broken_symlinks($dir, true);
2503+
// remove broken symlinks a second time after hardlink cleanup
2504+
$this->remove_broken_symlinks($jail_dir, true);
2505+
}
2506+
else { $app->log("update_jailkit_chroot: NOT searching for hardlinks in $jail_dir, options: ".print_r($options, true), LOGLEVEL_DEBUG); }
24942507
}
24952508

2509+
foreach ($multiple_links as $file) {
2510+
$app->log("update_jailkit_chroot: removing hardlinked file: $file", LOGLEVEL_DEBUG);
2511+
unlink($file);
2512+
}
24962513

2497-
$cmd = 'jk_update --jail='.escapeshellarg($home_dir) . $skips;
2498-
exec($cmd, $out, $ret);
2499-
foreach ($out as $line) {
2514+
$cmd = 'jk_update --jail=?' . $skips;
2515+
$this->exec_safe($cmd, $home_dir);
2516+
$app->log('jk_update returned: '.print_r($this->_last_exec_out, true), LOGLEVEL_DEBUG);
2517+
foreach ($this->_last_exec_out as $line) {
25002518
if (substr( $line, 0, 4 ) === "skip") {
25012519
continue;
25022520
}
2503-
if (preg_match('@^(? [^ ]+){6}(.+)'.preg_quote($home_dir, '@').'$@', $line, $matches)) {
2521+
if (preg_match('@^(?: [^ ]+){6}(.+)'.preg_quote($home_dir, '@').'$@', $line, $matches)) {
25042522
# remove deprecated files that jk_update failed to remove
25052523
if (is_file($matches[1])) {
2506-
$app->log("removing deprecated file which jk_update failed to remove: ".$matches[1], LOGLEVEL_DEBUG);
2524+
$app->log("update_jailkit_chroot: removing deprecated file which jk_update failed to remove: ".$matches[1], LOGLEVEL_DEBUG);
25072525
unlink($matches[1]);
25082526
} elseif (is_dir($matches[1])) {
2509-
$app->log("removing deprecated directory which jk_update failed to remove: ".$matches[1], LOGLEVEL_DEBUG);
2527+
$app->log("update_jailkit_chroot: removing deprecated directory which jk_update failed to remove: ".$matches[1], LOGLEVEL_DEBUG);
25102528
$this->rmdir($matches[1], true);
25112529
}
25122530
# unhandled error
2513-
$app->log("jk_update error for jail $home_dir: ".$matches[1], LOGLEVEL_DEBUG);
2531+
//$app->log("jk_update error for jail $home_dir: ".$matches[1], LOGLEVEL_DEBUG);
2532+
// at least for 3.2 beta, lets gather some of this info:
2533+
$app->log("jk_update error for jail $home_dir, feel free to pass to ispconfig developers: ".print_r( $matches, true), LOGLEVEL_DEBUG);
25142534
}
25152535
}
25162536

@@ -2528,20 +2548,20 @@ public function update_jailkit_chroot($home_dir, $sections = array(), $programs
25282548
}
25292549

25302550
// search for any hardlinked files which are now missing
2531-
if (!in_array('hardlink', $opts) && !in_array('allow_hardlink', $options)) {
2551+
if (!(in_array('hardlink', $opts) || in_array('allow_hardlink', $options))) {
25322552
foreach ($multiple_links as $file) {
25332553
if (!is_file($file)) {
25342554
// strip $home_dir from $file
2535-
if (substr($file, 0, strlen(rtrim($home_dir, '/'))) == strlen(rtrim($home_dir, '/'))) {
2555+
if (substr($file, 0, strlen(rtrim($home_dir, '/'))) == rtrim($home_dir, '/')) {
25362556
$file = substr($file, strlen(rtrim($home_dir, '/')));
25372557
}
25382558
if (is_file($file)) { // file exists in root
2539-
$app->log("file with multiple links still missing, running jk_cp to restore: $file", LOGLEVEL_DEBUG);
2559+
$app->log("update_jailkit_chroot: previously hardlinked file still missing, running jk_cp to restore: $file", LOGLEVEL_DEBUG);
25402560
$cmd = 'jk_cp -j ? ' . escapeshellarg($file);
25412561
$this->exec_safe($cmd, $home_dir);
25422562
} else {
25432563
// not necessarily an error
2544-
$app->log("previously hardlinked file was not found to restore: $file", LOGLEVEL_DEBUG);
2564+
$app->log("update_jailkit_chroot: previously hardlinked file was not restored and is no longer present in system: $file", LOGLEVEL_DEBUG);
25452565
}
25462566
}
25472567
}
@@ -2597,13 +2617,17 @@ public function delete_jailkit_chroot($home_dir) {
25972617
'sys',
25982618
'usr',
25992619
'var',
2620+
'run', # not used by jailkit, but added for cleanup
26002621
);
26012622

26022623
$removed = '';
26032624
foreach ($jailkit_directories as $dir) {
26042625
$jail_dir = rtrim($home_dir, '/') . '/'.$dir;
26052626

2606-
if (is_dir($jail_dir)) {
2627+
if (is_link($jail_dir)) {
2628+
unlink($jail_dir);
2629+
$removed .= ' /'.$dir;
2630+
} elseif (is_dir($jail_dir)) {
26072631
$this->rmdir($jail_dir, true);
26082632
$removed .= ' /'.$dir;
26092633
}
@@ -2612,10 +2636,11 @@ public function delete_jailkit_chroot($home_dir) {
26122636

26132637
$app->log("delete_jailkit_chroot: removed from jail $home_dir: $removed", LOGLEVEL_DEBUG);
26142638

2615-
// handle etc and home special
2639+
// remove /home if empty
26162640
$home = rtrim($home_dir, '/') . '/home';
26172641
@rmdir($home); # ok to fail if non-empty
26182642

2643+
// otherwise archive under /private
26192644
$private = rtrim($home_dir, '/') . '/private';
26202645
if (is_dir($home) && is_dir($private)) {
26212646
$archive = $private.'/home-'.date('c');

server/plugins-available/cron_jailkit_plugin.inc.php

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,20 @@ function _setup_jailkit_chroot()
232232
{
233233
global $app;
234234

235+
if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
236+
if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
237+
$options = array( 'hardlink', );
238+
} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
239+
$options = array();
240+
}
241+
} else {
242+
$options = array( 'allow_hardlink', );
243+
}
244+
235245
//check if the chroot environment is created yet if not create it with a list of program sections from the config
236246
if (!is_dir($this->parent_domain['document_root'].'/etc/jailkit'))
237247
{
238-
$app->system->create_jailkit_chroot($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_sections']);
248+
$app->system->create_jailkit_chroot($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_sections'], $options);
239249

240250
$this->app->log("Added jailkit chroot", LOGLEVEL_DEBUG);
241251

@@ -267,34 +277,26 @@ function _setup_jailkit_chroot()
267277
$app->system->file_put_contents($motd, $tpl->grab());
268278

269279
} else {
270-
$options = array( 'allow_hardlink', );
271-
if (isset($this->jailkit_config) && isset($this->jailkit_config['jailkit_hardlinks'])) {
272-
if ($this->jailkit_config['jailkit_hardlinks'] == 'yes') {
273-
$options = array( 'hardlink', );
274-
} elseif ($this->jailkit_config['jailkit_hardlinks'] == 'no') {
275-
unset($options['allow_hardlink']);
276-
}
277-
}
278280
// force update existing jails
279281
$options[] = 'force';
280282

281283
$sections = $this->jailkit_config['jailkit_chroot_app_sections'];
282284
$programs = $this->jailkit_config['jailkit_chroot_app_programs'];
283285

284-
$app->system->update_jailkit_chroot($this->data['new']['dir'], $sections, $programs, $options);
286+
$app->system->update_jailkit_chroot($this->parent_domain['document_root'], $sections, $programs, $options);
285287
}
286-
$this->_add_jailkit_programs();
287288

288-
// might need to update master db here? checking....
289+
$this->_add_jailkit_programs($options);
290+
291+
// this gets last_jailkit_update out of sync with master db, but that is ok,
292+
// as it is only used as a timestamp to moderate the frequency of updating on the slaves
289293
$app->db->query("UPDATE `web_domain` SET `last_jailkit_update` = NOW() WHERE `document_root` = ?", $this->data['new']['dir']);
290294
}
291295

292-
function _add_jailkit_programs()
296+
function _add_jailkit_programs($opts=array())
293297
{
294298
global $app;
295299

296-
$opts = array('force');
297-
298300
//copy over further programs and its libraries
299301
$app->system->create_jailkit_programs($this->parent_domain['document_root'], $this->jailkit_config['jailkit_chroot_app_programs'], $opts);
300302
$this->app->log("Added app programs to jailkit chroot", LOGLEVEL_DEBUG);

0 commit comments

Comments
 (0)