hi there

i just got an email from a company that i wrote a custom file upload script for 3 years ago, that the uploads didnt work anymore (they have, at least until june - i have no idea how much they used it)... here is the code:

<?php
//...
		if (!copy($newpic, $path . "deco/start/" . $newFilename)) {
			print "<div class=\"error\">" . $path . "deco/start/" . $newFilename . " could not be saved!</div>";
		}
		else {
			@unlink($newpic);
			print "<div class=\"error\">" . $newPic . " could not be deleted!</div>";
		}
//...
?>

here is the output:

Warning: copy(): open_basedir restriction in effect. File(/tmp/php0QqtRq) is not within the allowed path(s): (/home/oo002vfr) in /home/oo002vfr/www/home/admin/index.php on line 41

../deco/start/1100885795_sid.jpg could not be saved!

here is a part of the phpInfo php-core section:

Directive - Local Value - Master Value

max_execution_time - 30 - 30
max_input_time - 60 - 60
open_basedir - /home/oo002vfr - no value
post_max_size - 8M - 8M
register_globals - On - On
safe_mode - Off - Off
safe_mode_exec_dir - no value - no value
safe_mode_gid - Off - Off
safe_mode_include_dir no value no value
upload_max_filesize - 20M - 20M
upload_tmp_dir - /home/oo002vfr/www/uploads - no value

it doesnt seem like i can change the open_basedir value with ini_set() - even if i could: what should it be at to prevent this error?
i cannot access the php.ini, since they are on a shared server, i can email the company who runs it though.

any ideas are welcome. rock on.
sid

    Hi,

    I'm not completely sure but the problem could be that PHP can't access the directory
    /home/oo002vfr/www/uploads
    for some reason and falls back to /tmp as upload_tmp_dir.

    Check if the uploads directory exists and check the privileges of that directory. You might need to chmod the directory.

    Please post more code, especially the part that deals with the uploaded file (where $newpic is set).

    Thomas

      permissions are ok, the directory exists. it used to work like a charm when i worked on it the last time. since i am the only one who has access to the server, it can only be something the server company changed.

      here are all the essential parts of the code for this issue:

      <?php
      
      $path = "../";
      
      if ($newpic && $newpic != "none" && $newpic != "") {
      	$newFilename = date("U") . $newpic_name;
      	if (!copy($newpic, $path . "deco/start/" . $newFilename)) {
      		print "<div class=\"error\">" . $path . "deco/start/" . $newFilename . " konnte nicht gespeichert werden!</div>";
      	}
      	else {
      		@unlink($newpic);
      		print "<div class=\"error\">" . $unlink . " konnte nicht gel&ouml;scht werden!</div>";
      	}
      }
      
      
      print "<table>
      <form action=\"" . $_SERVER['PHP_SELF'] . "\" method=\"post\" enctype=\"multipart/form-data\">
      	<tr>
      		<td valign=\"top\">
      			<input type=\"file\" name=\"newpic\">
      		</td>
      	</tr>
      	<tr>
      		<td valign=\"top\">
      			text:
      		</td>
      		<td valign=\"top\">
      			<textarea name=\"newinfo\" cols=\"50\" rows=\"5\"></textarea>
      		</td>
      	</tr>
      	<tr>
      		<td valign=\"top\" colspan=\"2\" align=\"center\">
      			<input type=\"hidden\" name=\"action\" value=\"edit\">
      			<input type=\"submit\" value=\"edit\">
      		</td>
      	</tr>
      </form>
      </table>";
      
      ?>

      a var_dump shows the following:

      var_dump($newpic);
      
      OUTPUT:
      string(14) "/tmp/phpgX2YWY"
      
      var_dump($_FILES);
      
      OUTPUT:
      array(1) {
        ["newpic"]=>
        array(5) {
          ["name"]=>
          string(8) "_sid.jpg"
          ["type"]=>
          string(11) "image/pjpeg"
          ["tmp_name"]=>
          string(14) "/tmp/phpgX2YWY"
          ["error"]=>
          int(0)
          ["size"]=>
          int(992)
        }
      }
      

      thanks a bunch.
      sid

        Ok,

        the problem is that PHP uses /tmp as upload_tmp_dir for some reason despite the fact that the local value of that variable is inside the open_basedir. PHP seems to ignore that for some reason. Please post the complete output of the phpinfo script (save the HTML document and post it as attachment).

        Thomas

          Originally posted by tsinka
          Please post the complete output of the phpinfo script (save the HTML document and post it as attachment).

          bittesehr - there ya go. ("the.domain.com" is in the code instead of the original domain)

            Ok,

            this is a little bit complicated.

            First of all check if move_uploaded_file works (I'm not sure).

            There are some bug reports on that issue but no really useful answer so far. It seems that this problem occurs if PHP is running as e.g. apache module.

            I checked some servers I have access to and on all servers with open_basedir set the /tmp directory has been added to open_basedir (you can specify a directory list).

            One question: Which uid/gid and access rights do the scripts have ?

            EDIT: The PHP module on that server has been recompiled on that server so I think that it has something to do with that.

            Thomas

              hey thomas...

              alright - here are the infos you requested:

              UID: 1180
              GID: 100
              Access rights: i'm not all sure what you mean here, but all the scripts are chmod 0644 by default - the target directory for the images is 0777.

              move_uploaded_file worked like a charm - thanks for that hint. i should've thought of this before - still... it kinda bugs me that we havent been able to come up with a solution for the copy() issue.

              ill give the server guys in salzburg a call on monday if we can't figure out what happened there.

              rock on - sid

                about the difference between copy and move_uploaded_file.

                It is recommended to use move_uploaded_file to hande file uploads. Setting open_basedir applies some restrictions to certain functions like copy and move_uploaded_file.

                But the restrictions applied to move_uploaded_file are not that strong as the ones applied to copy since you can use that function only on the file(s) that have been uploaded.

                So this seems to be an expected behaviour of PHP (no solution ... no need to change anything, just make sure that you always use move_uploaded_file on uploaded files)

                EDIT: OK, the only solution is not to use open_basedir in that case but that would decrease security)

                Thomas

                  Write a Reply...