views:

35

answers:

1

Hey all,

I am working on a PHP web app on a Linux web server for grades and documents for a course that I am co-teaching. The page I am writing at the moment is for submitting assignments, where the student selects an assignment from a drop-down menu and then uploads the assignment and submits. On submit, all the information about the submission goes into a MySQL table, and the file is moved to a permanent location on the file system. Ideally, this would be something highly organized by assignment, student, and version, but all I want right now is to get the file upload working in principle, so for now it just sends stuff to the directory ~/phptest/ (permissions for which are set to 755, though I have tried 777 just for tests, and that didn't work either). Here is the code as it is now:

($dbh is an instance of an expanded DB handle class I created to make these specific DB transactions cleaner)


if(isset($_POST['submit'])) {
    $assignmentID = $_POST['assID'];
    $tmp = "/home/username/phptest/"; 
    $info = pathinfo($_FILES['file']['name']);
    $filename = $info['basename'];
    $ext = $info['extension'];
    if(1) { //strcmpall($ext,array('tar.gz','zip'))) {
        if($_FILES['file']['size'] < 1000000) {
            $path = $tmp . $filename;
            if(move_uploaded_file($_FILES['file']['tmp_name'], $path)) {
                $versionQuery = $dbh->select(array('version'),array('a01_submissions'),array("studentID='$studentID'","assignmentID='$assignmentID'"));
                if(count($versionQuery)) {
                    $versionArray = $dbh->colToArray($versionQuery,'version');
                    $version = max($versionArray)+1;
                }
                else $version = 1;
                echo "Version $version.\n";
                $week = $dbh->getOne('week','a01_assignments','id',$assignmentID);
                $dbh->insert("a01_submissions",array('studentID','assignmentID','version','filePath'),array($studentID,$assignmentID,$version,addslashes($newpath)));
                echo "File $filename sucessfully uploaded and stored at $newpath.\n";
            }
            else echo $moved . "
\n"; } else die("File cannot exceed 1MB"); } else die("Bad file extension."); } else { // HTML to display the submission screen }

My problem, though, is that move_uploaded_file only works for directories with 777 permissions. Closer inspection reveals that this is because PHP is uploading stuff as the user 'apache', and therefore can't write to directories owned by my username with o-w. I saw solutions posted by users in the PHP docs that suggested using chown to reclaim the files, but I don't have a high enough permission level to do this. Is there an elegant solution to this problem that does not involve trying to get my username higher permissions?

Thanks!

+1  A: 

Get the sysadmin to put you in the same user group as apache or ideally create a new group called something like developers and add the apache user and yourself to it.

Otherwise you could try using PHP's chmod or chown functions immediately after the file upload. If you run chmod($filepath, 0777); that should be a good test of whether it will work for you or not.

Treffynnon
If I want to use 755 though, wouldn't that still block writes from users in the same group? 755 is g-w and o-w. Or are you saying that 775 would be just as good as 755 if the group only contained my username and apache?
pr0crastin8r
755 will not work to write as a member of the same group. You will need to either use 764 or above (such as 775 or 765). See: http://www.csgnetwork.com/csgchmodcalc.html for an easy way to work this out.
Treffynnon
No I understand what the permissions bits are, I'm just worried about security. Are you saying that restricting the "writeable by others" bit is secure enough? I always thought the gold standard was 755, so I was wondering if there was any way to do what I want to do with groups and others at r-x. Or, what might be a better question, what is the most secure way to do what I want to do?
pr0crastin8r
755 if you only need read 765 if you need write
Treffynnon
If you need write then you need write so you have to set the perm - I don't see how you are ever going to get round that short of making it 755 and then copying the files to your own user dir for manipulation.
Treffynnon
Ok, good to know. Thanks!
pr0crastin8r