Link to home
Start Free TrialLog in
Avatar of mjburke
mjburkeFlag for United States of America

asked on

move_uploaded_file() does not move file into destination directory on W2K server

We are using PHP on a W2K server as the front-end to MS SQL database.

A script is used to upload text and a picture (optional) from authorized clients via HTML into a MS SQL database for display on our intranet/extranet according to the following code sniglet:

                  $query="INSERT INTO News (date, subject, description, enteredby, modifieddate,
                                            pic, picpath, Viewer)
                                 VALUES";
                  $user = $Page->user;
                  $moddate = date("m/d/Y");
                  $thepic=0;
                  $name="";
                  if($pic==1)
                  {
                     $thepic=1;
                     $name=$_FILES['userfile']['name'];
                     $tmp_name=$_FILES['userfile']['tmp_name'];
                     
                     $succees = move_uploaded_file
                                                   ($name, "C:\\CorpWebsite\\graphics\\picuploads\\$name");
                     if(!$success) echo("Upload unsuccessful!" . '<br>');

                     $success = move_uploaded_file
                                                      ($name, "C:\\ABNET\\secure\\graphics\\picuploads\\$name");
                     if (!$success) echo("Upload unsuccessful!" . '<br>');
                     
                  }

                  $subject=str_replace("'", "''", $subject);
                  $descript=str_replace("'", "''", $descript);
                  $query.=" ('$date', '$subject', '$descript', '$user', '$moddate',                                
                                           $thepic, '$userfile', '$aud')";

If a picture is included, it is uploaded to two different locations - one for our intranet and a www site.  Each of the $success variables are assigned false even though the jpeg file successfully appears on the external website.  However, the image upload to our intranet (ABNET) results in a box with an "X" in it.  When I inspect the upload folder, it does not contain the appropriate jpeg file, and hence the missing image.

I have the following in my HTML:

<form enctype="multipart/form-data" action="update2.php" method=POST>
   <input type="hidden" name="MAX_FILE_SIZE" value="100000">

I've checked the W2K security on the upload folder (and entire path) and I am authorized to read, write and execute.  I have tried to use copy($source, $dest) in place of move_uploaded_file() with the same result.  I've also tried substituting $tmp_name for $name (and vice-versa) as arguments in the move_uploaded_file() statement to no avail.  Something is preventing the transfer of the image from the temporary location to the final location but damn if I can figure it out.  Please help - this is driving me bonkers.
Avatar of Diablo84
Diablo84

you should use the temp name to move it so try...

                     $success = move_uploaded_file
                                                   ($tmp_name, "C:\\CorpWebsite\\graphics\\picuploads\\$name");
                     if(!$success) echo("Upload unsuccessful!" . '<br>');

                     $success = move_uploaded_file
                                                      ($tmp_name, "C:\\ABNET\\secure\\graphics\\picuploads\\$name");
                     if (!$success) echo("Upload unsuccessful!" . '<br>');

also note the typo which i corrected, that might have been the cause

also i cant remember if move_uploaded_file physically moves the file on the server of if it copies it from the uploaded location (later to clear out the cache in the temp upload file). If it is the former then you wont be able to move it twice to two sepearte locations so you may have to copy it the first time

ie.

                     $success = copy
                                                   ($tmp_name, "C:\\CorpWebsite\\graphics\\picuploads\\$name");
                     if(!$success) echo("Upload unsuccessful!" . '<br>');

                     $success = move_uploaded_file
                                                      ($tmp_name, "C:\\ABNET\\secure\\graphics\\picuploads\\$name");
                     if (!$success) echo("Upload unsuccessful!" . '<br>');
try this..


        if($_FILES['userfile']['size']!=0)
         {
                 $name=$_FILES['userfile']['name'];
                 $tmp_name=$_FILES['userfile']['tmp_name'];
                if( move_uploaded_file($tmp_name,"C:\\ABNET\\secure\\graphics\\picuploads\\$name"))
                 {
                                        echo("Upload successful!" . '<br>');
                 }else{
                          echo("Upload unsuccessful!" . '<br>');
                 }
         }else
         {
              echo("Upload unsuccessful!" . '<br>');
         }
                     
There is a PHP function called is_uploaded_file.

http://uk2.php.net/is_uploaded_file

From the manual ...

is_uploaded_file
(PHP 3>= 3.0.17, PHP 4 >= 4.0.3)

is_uploaded_file -- Tells whether the file was uploaded via HTTP POST
Description
bool is_uploaded_file ( string filename)


Returns TRUE if the file named by filename was uploaded via HTTP POST. This is useful to help ensure that a malicious user hasn't tried to trick the script into working on files upon which it should not be working--for instance, /etc/passwd.

This sort of check is especially important if there is any chance that anything done with uploaded files could reveal their contents to the user, or even to other users on the same system.

is_uploaded_file() is available only in versions of PHP 3 after PHP 3.0.16, and in versions of PHP 4 after 4.0.2. If you are stuck using an earlier version, you can use the following function to help protect yourself:

Note: The following example will not work in versions of PHP 4 after 4.0.2. It depends on internal functionality of PHP which changed after that version.

<?php
/* Userland test for uploaded file. */
function is_uploaded_file($filename)
{
    if (!$tmp_file = get_cfg_var('upload_tmp_dir')) {
        $tmp_file = dirname(tempnam('', ''));
    }
    $tmp_file .= '/' . basename($filename);
    /* User might have trailing slash in php.ini... */
    return (ereg_replace('/+', '/', $tmp_file) == $filename);
}

/* This is how to use it, since you also don't have
* move_uploaded_file() in these older versions: */
if (is_uploaded_file($HTTP_POST_FILES['userfile'])) {
    copy($HTTP_POST_FILES['userfile'], "/place/to/put/uploaded/file");
} else {
    echo "Possible file upload attack: filename '$HTTP_POST_FILES[userfile]'.";
}
?>  


See also move_uploaded_file(), and the section Handling file uploads for a simple usage example




And a note in the User notes of the online manual ...

schoenma at web dot de
05-Feb-2004 02:28
For proper working, the function is_uploaded_file ()
needs an argument like $_FILES['mainfile']['tmp_name'],
- the name of the uploaded file on the clients machine $_FILES['mainfile']['name'] does not work.


This may help to see if the file you THINK was uploaded actually was.

Richard.
Avatar of mjburke

ASKER

Diablo84:  I've implemented your solution but the image file was not copied/moved to the destination directory.

ushastry:  I've echoed out the size of the tmp file and it was 27543 bytes, which matches the size attribute of the original jpg.

RQuadling:  

I included the following code per your recommendation:

     $tmp_name=$_FILES['userfile']['tmp_name'];
     echo("Size of file: " . $_FILES['userfile']['size'] . '<br>');
                     
     if (is_uploaded_file($tmp_name))
     {
           copy($tmp_name, "C:\\ABNET\\secure\\graphics\\picuploads\\$name");
           copy($tmp_name, "C:\\CorpWebsite\\graphics\\picuploads\\$name");
     }
     
     else echo "Copy unsuccessful!";

The return value to is_uploaded_file was 1 so the copy operations were executed.  However, the images were not available on the webpages as they were not in their destination directories.



Try...

if (is_uploaded_file($tmp_name))
     {
           move_uploaded_file($tmp_name, "C:\\ABNET\\secure\\graphics\\picuploads\\$name");
           copy("C:\\ABNET\\secure\\graphics\\picuploads\\$name", "C:\\CorpWebsite\\graphics\\picuploads\\$name");
     }
Identical to RQua..

$name=$_FILES['userfile']['name'];
$tmp_name=$_FILES['userfile']['tmp_name'];
$sourceFile ="C:/ABNET/secure/graphics/picuploads/".$name;
$targetFile  = "C:/CorpWebsite/graphics/picuploads/".$name;


if (is_uploaded_file($tmp_name))
     {
           move_uploaded_file($tmp_name,$sourceFile);
           copy($sourceFile,$targetFile);
     }
Avatar of mjburke

ASKER

Gentlemen,

Tried the following:

   $int_dest_file = "C:/ABNET/secure/graphics/picuploads/" . $name;
   $ext_dest_file = "C:/CorpWebsite/graphics/picuploads/" . $name;

   if (is_uploaded_file($tmp_name))
   {
      $move = move_uploaded_file($tmp_name, $ext_dest_file);
      echo "Move to CorpWebsite: " . $move . '<br>';
      $move = copy($ext_dest_file, $int_dest_file);
      echo "Move to ABNET: " . $move . '<br>';
   }

   else echo "File transfer unsuccessful" . '<br>';

The output is:

   Move to CorpWebsite: 1
   Move to ABNET:

The image appears perfectly on the page for CorpWebsite.  However, only a border of the image (sized the same as the actual image) appears on the ABNET page.  I don't understand why the copy function did not return a value - its as though it did not execute.
First, try swapping the sequence around and make sure that the webserver has permissions to write to the corp directory.

If you are connecting to a certain site, does this somehow infer some sort of user which prohibits writing to other directories? Do you have a restricted PHP installation? Try ...

<?php

$fp = fopen("C:/ABNET/secure/graphics/picuploads/1.test","wt") or die("Cannot create file in secure ABNET directory.");

?>

Hi  mjburke,


I tested this stuff on Win2k+Apache+PHP4.3.X & it is doing as expected..

<form enctype="multipart/form-data" action="up.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="30000">
Send this file: <input name="userfile" type="file">
<input type="submit" value="Send File">
</form>
<?

$name=$_FILES['userfile']['name'];
$tmp_name=$_FILES['userfile']['tmp_name'];
$sourceFile ="C:/ABNET/secure/graphics/picuploads/".$name;
$targetFile  = "C:/CorpWebsite/graphics/picuploads/".$name;


if (is_uploaded_file($tmp_name))
     {
           move_uploaded_file($tmp_name,$sourceFile);
           copy($sourceFile,$targetFile);
     }

if (file_exists($sourceFile)) {
    print "The file $sourceFile exists";
} else {
    print "The file $sourceFile does not exist";
}

if (file_exists($targetFile)) {
    print "The file $targetFile exists";
} else {
    print "The file $targetFile does not exist";
}


?>


Check out here
http://us4.php.net/copy

I think the problem is in copy() only..

Hope this helps!
Avatar of mjburke

ASKER

Tried the following:

$fp = fopen("C:/ABNET/secure/graphics/picuploads/1.test","wt") or die("Cannot create file in secure ABNET directory.");

I could not create a file in the destination directory.  I've checked the security rights on the folder and I have full access.  A real dome-scratcher.
ASKER CERTIFIED SOLUTION
Avatar of Richard Quadling
Richard Quadling
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of mjburke

ASKER


RQuadling,

The 2nd option in your last post inspired me to check security priviledges on the destination folders for CorpWebsite and ABNET servers.  An internet guest account ISUR was apparently created by IIS during installation.  It was then tagged to both servers to allow access.  However, this particular account did not have write priviledges to the ABNET site, thus inhibiting the creation or upload of files to the destination folder.  I simply added write access and voila...the image now appears very nicely on both pages.  Thanks to everybody who contributed ideas to help fix my mess.