@@ -941,6 +941,22 @@ function move($file1, $file2) {
941941 return $ return_var == 0 ? true : false ;
942942 }
943943
944+ function rmdir ($ dir , $ recursive =false ) {
945+ $ dir = rtrim ($ dir , '/ ' );
946+ if (is_dir ($ dir )) {
947+ $ objects = scandir ($ dir );
948+ foreach ($ objects as $ object ) {
949+ if ($ object != ". " && $ object != ".. " && $ recursive ) {
950+ if (filetype ($ dir .'/ ' .$ object ) == 'dir ' )
951+ $ this ->rmdir ($ dir .'/ ' .$ object , $ recursive );
952+ else unlink ($ dir .'/ ' .$ object );
953+ }
954+ }
955+ reset ($ objects );
956+ rmdir ($ dir );
957+ }
958+ }
959+
944960 function touch ($ file , $ allow_symlink = false ){
945961 global $ app ;
946962 if ($ allow_symlink == false && @file_exists ($ file ) && $ this ->checkpath ($ file ) == false ) {
@@ -2223,61 +2239,192 @@ public function create_jailkit_user($username, $home_dir, $user_home_dir, $shell
22232239 return true ;
22242240 }
22252241
2226- public function create_jailkit_programs ($ home_dir , $ programs = array ()) {
2242+ public function create_jailkit_chroot ($ home_dir , $ app_sections = array (), $ options = array ()) {
2243+ if (!is_dir ($ home_dir )) {
2244+ $ app ->log ("Jail directory does not exist: $ homedir " , LOGLEVEL_WARN );
2245+ return false ;
2246+ }
2247+ if (empty ($ app_sections )) {
2248+ return true ;
2249+ } elseif (is_string ($ app_sections )) {
2250+ $ app_sections = preg_split ('/[\s,]+/ ' , $ app_sections );
2251+ }
2252+
2253+ // Change ownership of the chroot directory to root
2254+ $ this ->chown ($ home_dir , 'root ' );
2255+ $ this ->chgrp ($ home_dir , 'root ' );
2256+
2257+ $ program_args = '' ;
2258+ foreach ($ options as $ opt ) {
2259+ switch ($ opt ) {
2260+ case '-k|hardlink ' :
2261+ $ program_args .= ' -k ' ;
2262+ break ;
2263+ case '-f|force ' :
2264+ $ program_args .= ' -f ' ;
2265+ break ;
2266+ }
2267+ }
2268+ # /etc/jailkit/jk_init.ini is the default path, probably not needed?
2269+ $ program_args .= ' -c /etc/jailkit/jk_init.ini -j ? ' ;
2270+ foreach ($ app_sections as $ app_section ) {
2271+ # should check that section exists with jk_init --list ?
2272+ $ program_args .= ' ' . escapeshellarg ($ app_section );
2273+ }
2274+
2275+ // Initialize the chroot into the specified directory with the specified applications
2276+ $ cmd = 'jk_init ' . $ program_args ;
2277+ $ this ->exec_safe ($ cmd , $ home_dir );
2278+
2279+ // Create the temp directory
2280+ if (!is_dir ($ home_dir . '/tmp ' )) {
2281+ $ this ->mkdirpath ($ home_dir . '/tmp ' , 0770 );
2282+ } else {
2283+ $ this ->chmod ($ home_dir . '/tmp ' , 0770 , true );
2284+ }
2285+
2286+ // Fix permissions of the root firectory
2287+ $ this ->chmod ($ home_dir . '/bin ' , 0755 , true ); // was chmod g-w $CHROOT_HOMEDIR/bin
2288+
2289+ return true ;
2290+ }
2291+
2292+ public function create_jailkit_programs ($ home_dir , $ programs = array (), $ options = array ()) {
2293+ if (!is_dir ($ home_dir )) {
2294+ $ app ->log ("Jail directory does not exist: $ homedir " , LOGLEVEL_WARN );
2295+ return false ;
2296+ }
22272297 if (empty ($ programs )) {
22282298 return true ;
22292299 } elseif (is_string ($ programs )) {
22302300 $ programs = preg_split ('/[\s,]+/ ' , $ programs );
22312301 }
2302+
2303+ # prohibit ill-advised copying paths known to be sensitive/problematic
2304+ # (easy to bypass if needed, eg. use /./etc)
2305+ $ blacklisted_paths_regex = array (
2306+ '|^/$| ' ,
2307+ '|^/proc(/.*)?$| ' ,
2308+ '|^/sys(/.*)?$| ' ,
2309+ '|^/etc/?$| ' ,
2310+ '|^/dev/?$| ' ,
2311+ '|^/tmp/?$| ' ,
2312+ '|^/run/?$| ' ,
2313+ '|^/boot/?$| ' ,
2314+ );
2315+
22322316 $ program_args = '' ;
2317+ foreach ($ options as $ opt ) {
2318+ switch ($ opt ) {
2319+ case '-k|hardlink ' :
2320+ $ program_args .= ' -k ' ;
2321+ break ;
2322+ case '-f|force ' :
2323+ $ program_args .= ' -f ' ;
2324+ break ;
2325+ }
2326+ }
2327+ $ program_args .= ' -j ? ' ;
2328+
2329+ $ bad_paths = array ();
22332330 foreach ($ programs as $ prog ) {
2234- $ program_args .= ' ' . escapeshellarg ($ prog );
2331+ foreach ($ blacklisted_paths_regex as $ re ) {
2332+ if (preg_match ($ re , $ prog , $ matches )) {
2333+ $ bad_paths [] = $ matches [0 ];
2334+ }
2335+ }
2336+ if (count ($ bad_paths ) > 0 ) {
2337+ $ app ->log ("Prohibited path not added to jail $ homedir: " . implode (", " , $ bad_paths ), LOGLEVEL_WARN );
2338+ } else {
2339+ $ program_args .= ' ' . escapeshellarg ($ prog );
2340+ }
22352341 }
22362342
2237- $ cmd = 'jk_cp -j ? ' . $ program_args ;
2238- $ this ->exec_safe ($ cmd , $ home_dir );
2343+ if (count ($ programs ) > count ($ bad_paths )) {
2344+ $ cmd = 'jk_cp ' . $ program_args ;
2345+ $ this ->exec_safe ($ cmd , $ home_dir );
2346+ }
22392347
22402348 return true ;
22412349 }
22422350
2243- public function create_jailkit_chroot ($ home_dir , $ app_sections = array ()) {
2244- if (empty ($ app_sections )) {
2245- return true ;
2246- } elseif (is_string ($ app_sections )) {
2247- $ app_sections = preg_split ('/[\s,]+/ ' , $ app_sections );
2351+ public function update_jailkit_chroot ($ home_dir , $ sections = array (), $ programs = array (), $ options = array ()) {
2352+ if (!is_dir ($ home_dir )) {
2353+ $ app ->log ("Jail directory does not exist: $ homedir " , LOGLEVEL_WARN );
2354+ return false ;
2355+ }
2356+
2357+ $ opts = array ('force ' );
2358+ foreach ($ options as $ opt ) {
2359+ switch ($ opt ) {
2360+ case '-k|hardlink ' :
2361+ $ opts [] = 'hardlink ' ;
2362+ break ;
2363+ }
22482364 }
22492365
22502366 // Change ownership of the chroot directory to root
22512367 $ this ->chown ($ home_dir , 'root ' );
22522368 $ this ->chgrp ($ home_dir , 'root ' );
22532369
2254- $ app_args = '' ;
2255- foreach ($ app_sections as $ app_section ) {
2256- $ app_args .= ' ' . escapeshellarg ($ app_section );
2370+ $ jailkit_directories = array (
2371+ 'bin ' ,
2372+ 'dev ' ,
2373+ 'etc ' ,
2374+ 'lib ' ,
2375+ 'lib32 ' ,
2376+ 'lib64 ' ,
2377+ 'opt ' ,
2378+ 'sys ' ,
2379+ 'usr ' ,
2380+ 'var ' ,
2381+ );
2382+
2383+ foreach ($ jailkit_directories as $ dir ) {
2384+ $ root_dir = '/ ' .$ dir ;
2385+ $ jail_dir = rtrim ($ home_dir , '/ ' ) . '/ ' .$ dir ;
2386+
2387+ if (!is_dir ($ jail_dir )) {
2388+ continue ;
2389+ }
2390+
2391+ // if directory exists in jail but not in root, remove it
2392+ if (is_dir ($ jail_dir ) && !is_dir ($ root_dir )) {
2393+ $ this ->rmdir ($ jail_dir , true );
2394+ continue ;
2395+ }
2396+
2397+ // remove dangling symlinks
2398+ $ app ->log ("TODO: search for and remove dangling symlinks " , LOGLEVEL_DEBUG );
2399+
2400+ // search for and remove hardlinked
2401+ if (!in_array ($ opts , 'hardlink ' ) && !in_array ($ options , 'allow_hardlink ' )) {
2402+ $ app ->log ("TODO: search for and remove hardlinked files " , LOGLEVEL_DEBUG );
2403+ // search for and save list of files
2404+ }
22572405 }
22582406
2259- // Initialize the chroot into the specified directory with the specified applications
2260- $ cmd = 'jk_init -f -c /etc/jailkit/jk_init.ini -j ? ' . $ app_args ;
2261- $ this ->exec_safe ($ cmd , $ home_dir );
2407+ // reinstall jailkit sections and programs
2408+ if (!(empty ($ sections ) && empty ($ programs ))) {
2409+ $ this ->create_jailkit_chroot ($ home_dir , $ sections , $ opts );
2410+ $ this ->create_jailkit_programs ($ home_dir , $ programs , $ opts );
2411+ }
22622412
22632413 // Create the temp directory
22642414 if (!is_dir ($ home_dir . '/tmp ' )) {
2265- $ this ->mkdirpath ($ home_dir . '/tmp ' , 0777 );
2415+ $ this ->mkdirpath ($ home_dir . '/tmp ' , 0770 );
22662416 } else {
2267- $ this ->chmod ($ home_dir . '/tmp ' , 0777 , true );
2417+ $ this ->chmod ($ home_dir . '/tmp ' , 0770 , true );
2418+ }
2419+
2420+ // search for and remove hardlinked
2421+ if (!in_array ($ opts , 'hardlink ' ) && !in_array ($ options , 'allow_hardlink ' )) {
2422+ $ app ->log ("TODO: search for hardlinked files now missing and add back " , LOGLEVEL_DEBUG );
22682423 }
22692424
22702425 // Fix permissions of the root firectory
22712426 $ this ->chmod ($ home_dir . '/bin ' , 0755 , true ); // was chmod g-w $CHROOT_HOMEDIR/bin
22722427
2273- // mysql needs the socket in the chrooted environment
2274- $ this ->mkdirpath ($ home_dir . '/var/run/mysqld ' );
2275-
2276- // ln /var/run/mysqld/mysqld.sock $CHROOT_HOMEDIR/var/run/mysqld/mysqld.sock
2277- if (!file_exists ("/var/run/mysqld/mysqld.sock " )) {
2278- $ this ->exec_safe ('ln ? ? ' , '/var/run/mysqld/mysqld.sock ' , $ home_dir . '/var/run/mysqld/mysqld.sock ' );
2279- }
2280-
22812428 return true ;
22822429 }
22832430
0 commit comments