Jump to content

Recommended Posts

I've been working on a helper method for writing files, and would like some feedback. The method intends to write a file to the filesystem. If the directory does not exist, it will make it (recursively). Default permissions are applied to dir and file if either did not exist, otherwise original permissions are kept.

class File {

    public function write_file( $full_path, $data, $mode = 'wb', $f_perm = 0644, $d_perm = 0755 )
    {
        $dir = pathinfo( $full_path, PATHINFO_DIRNAME );

        if( ! is_dir( $dir ) )
        {
            if( ! mkdir( $dir, 0777, TRUE ) )
            {
                return FALSE;
            }
        }
        else
        {
            $d_perm = fileperms( $dir );
            @chmod( $dir, 0777 );

            if( is_file( $full_path ) )
            {
                $f_perm = fileperms( $full_path );
                @chmod( $full_path, 0777 );
            }
        }

        $write_success = FALSE;

        if( $fp = @fopen( $full_path, $mode ) )
        {
            flock( $fp, LOCK_EX );

            if( fwrite( $fp, $data ) !== FALSE )
            {
                $write_success = TRUE;
            }

            flock( $fp, LOCK_UN );
            fclose( $fp );
        }

        @chmod( $full_path, $f_perm );
        @chmod( $dir, $d_perm );

        return $write_success;
    }
    
    // -----------------------------------------------------------------------
}
Link to comment
https://forums.phpfreaks.com/topic/286070-please-review-file-writing-method/
Share on other sites

It could be anywhere on the server, because the first param is the full server path. I'll be using this primarily for logs and storage of dynamically generated pdfs. It will not be used for uploads.

Edited by sKunKbad

I wouldn't bother with a class for just one function like that. Rather I would just make the function and include it. If you want to do a class, I'd re-work things a bit. Eg:

 

class Filesystem { 
	public function write_file($full_path, $data, $mode='wb', $f_perm=0644, $d_perm=0755){
		if (!$this->mkdir(dirname($full_path), $d_perm)){
			return false;
		}	

		$success=false;
		$fp = fopen($full_path, $mode);
		if ($fp && flock($fp, LOCK_EX)){
			chmod($full_path, $f_perm);	
			if (fwrite($fp, $data) === strlen($data)){
				$success = true;
			}

			flock($fp, LOCK_UN);
		}
		if ($fp) fclose($fp);

		return $success;
	}

	public function mkdir($path, $d_perm=0755){
		if (!is_dir($path)){
			return mkdir($path, $d_perm, true);
		}

		return true;
	}
}
You could extend it further to provide methods for deleting files, reading files, virtual root, etc.

It could be anywhere on the server, because the first param is the full server path. I'll be using this primarily for logs and storage of dynamically generated pdfs. It will not be used for uploads.

Then, before writing whatever it may be, I'd suggest to encapsulate the fileserver using a container or some virtualization, personally I recommend LXC, if the server is running on Linux.

I see where you're going with your suggestions, but this is intended to be a generic method, used for any hosting environment. But for the sake of learning a little more about your suggestion, can you answer a question. Is the purpose of LXC to run an independent fileserver, which has no affiliation with the host server, so that files written throughh this method cannot be an attack vector to the host?

 

Is the purpose of LXC to run an independent fileserver, which has no affiliation with the host server, so that files written throughh this method cannot be an attack vector to the host?

 

Short answer - yes! Do you know what chroot on Unix/Linux is?

I wouldn't bother with a class for just one function like that. Rather I would just make the function and include it. If you want to do a class, I'd re-work things a bit. Eg:

 

class Filesystem { 
	public function write_file($full_path, $data, $mode='wb', $f_perm=0644, $d_perm=0755){
		if (!$this->mkdir(dirname($full_path), $d_perm)){
			return false;
		}	

		$success=false;
		$fp = fopen($full_path, $mode);
		if ($fp && flock($fp, LOCK_EX)){
			chmod($full_path, $f_perm);	
			if (fwrite($fp, $data) === strlen($data)){
				$success = true;
			}

			flock($fp, LOCK_UN);
		}
		if ($fp) fclose($fp);

		return $success;
	}

	public function mkdir($path, $d_perm=0755){
		if (!is_dir($path)){
			return mkdir($path, $d_perm, true);
		}

		return true;
	}
}
You could extend it further to provide methods for deleting files, reading files, virtual root, etc.

 

 

I only chose to show one method. There are a few others, but didn't want to post a bunch of code that was off topic.

Hey sKunKbad,

the "chroot" is an operation on the operating systems level changing the apparent root directory for the current able to running process with root priv. This technique allows you to have multiple chroot enviroments as separated domains on the main host. The result afterward is, you will be using the current kernel version of the host and that kernel being shared to others chroot'ed environments on the same machine. One of the problem I encountered using chroot through the years that all processes inside chroot'ed env aren't visible from outside (not able to kill or modified them ), and the most important thing it was, if I want to use chroot'ed programs which need to have a root access from the host, that was impossible (in standart way) by using chroot enviroment, because all modified environment cannot named and therefore they don't access to files, programs and so on outside the designated directory tree. Fortunately, lxc resolve the problems which I mentioned above. If you have a specific question, we're still here :)

Edited by jazzman1
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.