chmod - file does not exist - php

I got a file that's located in
/uploads/original/img_329020110508094322.jpg
When I do <img src="/uploads/original/img_329020110508094322.jpg" />
It will display properly
I want to change the user rights to 0606, so I do chmod($this->fileName, 0606);
($this->fileName stores the path above) but all I get is file or directory does not exist.
Why?

chmod() operates on your filesystem. You must point to the image file within your filesystem, not within your web server.

cause your path is relative to your web root. add the location of your web root before the file name, and chmod should work.
what i'm trying to say is that chmod uses exact paths on your file system :)

Related

PHP is_writable error returns not writable

I have this code
if(is_writable($destination)){
print "destination is writable";
}
else {
print "destination is not writable";
}
$destination is a relative path like ../subdir/dir/currectDir/ and I have checked and the permission is 777 but this code above returns "destination is not writable" and I don't understand why. Can someone help me? Thanks
There are many reasons why a directory may not be writable, aside from permissions. Some of them are:
The directory is outside of the paths which PHP is able to write to because of open_basedir restrictions
The directory is on a drive which is mounted as read-only
The directory has immutable or appendonly attributes set
The filesystem is corrupt
However, my guess in this case would be that the path you are using is not correct. Try running
echo getcwd();
Just before your is_writable() call.
It will tell you the current directory the PHP script is running in, and from there you should be able to work out the correct relative path. Not that if running a PHP script from the command line its path will be that of the current directory, whereas running via a web server such as Apache it will usually be the public_html or httpdocs directory. It may have also been changed earlier on in the script execution.
You can also specify an absolute path (e.g. /home/youruser/public_html/subdir/dir/currectDir)
I can't comment, so I have to respond here but it looks as though the path (you posted a relative path, not an absolute path by the way) is incorrect - have you tried
var_dump(file_exists($destination));
first, to determine if you are looking in the right place for your directory?

Upload files to the folder outside root folder in Linux server?

In my project, I have to upload some video files to a folder which lies outside the root folder. I am using simple php function move_uploaded_file to upload the file. I have tried with the code below.
$source = $_FILES['Filedata']['tmp_name'];
$targetFile = '/usr/local/WowzaMediaServer-3.1.1/content/video.mp4'
move_uploaded_file($source,$targetFile);
But it is not working. Can we done it through move_uploaded_file. if not, suggest a better option to do this.
I have seen some similar question but nothing helps. So any help would be appreciated..
Are you sure you're not in a chroot jail?
If so, your "absolute" path name could be pointing to the wrong place-- somewhere that doesn't exist.
If so, change the path to point to somewhere within the jail.
It may be necessary to mount --bind the directory you want this to go in into some location within the jail. (Note that a symbolic link will not work for getting out of jail.)
More than likely this is a simple permissions issue and quite easy to solve.
Find the user that apache uses. To do this open up your httpd.conf file and look for something like:
User apache
Group apache
Change the ownership of the folder that you're trying to upload to.
chown -R apache.apache /usr/local/WowzaMediaServer-3.1.1/content/
Change the permissions of the folder
chmod -R 775 /usr/local/WowzaMediaServer-3.1.1/content/
And that should be that.
I'm going to assume you're using Apache for the purposes of this answer.
First off, is the file being uploaded ok? One possible reason you might have trouble is that the tmp directory isn't writable by the webserver, or readable come to that. Assuming that's ok then move_uploaded_file should work fine.
Create a folder next to your DOCUMENT_ROOT, let's call it "filestore". Make sure it's writable by www-data or whichever user runs apache. Now, you should be able to move the files into that folder. Note they will be owned by www-data:www-data typically - or whatever user and group your server is set up to run as. The reason I put the "filestore" folder next to the DOCUMENT_ROOT folder is that you can be sure the webserver can read the file path up to DOCUMENT_ROOT. Otherwise you run the risk of a folder part way up the path not being readable, and that'll stop you dead. e.g. if you have /usr/local/media as your target folder and /usr/local isn't readable (and executable) by the webserver, you're toast.
If all this works and you absolutely must have you media elsewhere, you can have the "filestore" folder anywhere so long as the whole path to it is read/executable by the webserver. Check each directory in the path.
If these uploaded files are being downloaded by other users via the web then the "filestore" folder only needs to have permissions of 700 since it's always going to be the web server's user which reads them. If other users need access, typically because other software running as a different user needs to use them then you might need permissions to be 750 to allow group members to read (and execute) the directory. You'll also need to add that other user to the www-data group.
For downloads you will need to write a simple script which dumps the file to the browser after doing some authentication checks. That way, you avoid having the media accessible just via http without having any authentication done first - which could make your service into an attractive place for illegal files (copyright violations being the least concern here).
This is a dangerous approach as it gives root privileges to the apache user, so use with caution.
Add the apache user to the list of sudoers - which will let you execute commands as root in php via system('sudo the_command'). Then move the uploaded file to a temporary location that the apache user can write do (eg. create a 'tmp' directory in the doc root). Then use system("sudo mv \"$source\" \"$destination\""); to move the temporary file to it's final location.
You can find the apache user by executing <?php echo exec('whoami'); ?>. Then add the following entry to sudoers the-apache-user ALL=(ALL) NOPASSWD: ALL. Use visudo to add the sudoer entry.
Example:
$source = $_FILES['Filedata']['tmp_name'];
$targetFile = '/usr/local/WowzaMediaServer-3.1.1/content/video.mp4'
$tempLocation = 'tmp/temp-file.mp4';
move_uploaded_file($source, $tempLocation);
system('sudo mv "' . $tempLocation . '" "' . $targetFile . '"');
Edit: Related question - How to run PHP exec() as root?
Always you face a problem with your code, look at the server log or easier turn on errors display. That said, your problem could be related to upload_tmp_dir setting. Check what a phpinfo() tells about that or look at your php.inifile.
A better solution would be to write the file somewhere where you can write (i.e. under the webroot) and then create a symlink from the media directory to be to where you wrote it.
For example:
Web Root is /var/www/html
You want it at /usr/local/WowzaMediaServer-3.1.1/content/
Create directory /var/www/html/mediaserver/content/
Make permissions on /var/www/html/mediaserver/content/ 777 (so apache can write to it)
Copy files from /usr/local/WowzaMediaServer-3.1.1/content/ to /var/www/html/mediaserver/content/
Delete /usr/local/WowzaMediaServer-3.1.1/content/ (just the "content" directory)
Create symlink from /usr/local/WowzaMediaServer-3.1.1/content/ to /var/www/html/mediaserver/content/
Then you have permissions to read/write, and the media server should too. Only issue would be if the media server is trained not to read symlinks - but you can find that out quickly enough.

Image Display in PHP

I want to display image through PHP.
When I put image in /var/www/ directory then it is working fine, I am giving full path.
But when I put image in some other directory (say home) then it is not displaying.
Usually, servers have some kind of sandbox which prevent your code to access files outside of it for security reasons.
I encourage you to put all data you want your server to be able to access inside its folders (/var/www directory or subdirectories of it)
First off, you should really check your error logs as they will probably point you in the right direction.
Without more information, I'd have an educated guess that the Apache user does not have rights to the file and/or the containing directories.
You can change permissions using the chown and chmod commands in a shell.
EDIT: But don't allow access to any dir with sensitive data (e.g. your home directory) to the webserver!

require_once(../../path/to/script.php) failed to open stream permission denied

See an example here: http://mattpotts.com/portal/
I put an includeme.htm in each directory on the required path to find the point of failure. It works fine on my local machine (windows) with the same directory structure but fails on my remote (linux) server.
Directory structure:
+-firefli/ drwx--x--x
+-private_html/ drwx------
+-foo/ drwxr-xr-x
+-bar/ drwxr-xr-x
+-portal/ drwxr-wr-w
+-public_html/ drwxr-wr-w
+-foo/ drwxr-wr-w
+-portal/ drwxr-wr-w
The permissions confirm that it's the private_html directory causing the trouble. Hopefully you can see the purpose of the directory structure, I don't know if it's a common way of doing things but it works for me. Well, until now.
I've gone a very long way around asking it but my question is simply this: is there anything wrong with setting private_html to be drwxr-xr-x? Given that I do not want it to be accessible via the web. But the permissions shouldn't do that should they? Because it's apache making the public_html directory accessible via http.
You shouldn't need to block out web users with folder/file permissions on private_html, as it's outside the web root. As you say, web users can only get to stuff in public_html
For future debugging speed, if you have a relative web path you can convert it to a real path using realpath:
$path = realpath('../../private_html');
// $path is now /public_html/foo/private.html or whatever
Well, if you have set up your DocumentRoot correctly to point to public_html, it won't be accessible from the web, no matter what permissions you put on it.
The Private HTMl is not accessible from the web without you putting in a .htaccess file that would redirect it. If you don't know what that means/how to do that, you are safe.
You should be fine setting these permissions to whatever your script needs.
what are the user:group for private_html? The web server needs to be either a member of the group or the owner of the file. In order to read the directory contents the dirctory needs to have the execute permission for the webserver to open it. Essentially they should have the same user:group as public_html. You just want to disallow the write permission. tot he webserver. If you have set your document root to public_html private_html is not accessible via the web no matter what the permissions. Also, i always use realpath on the path arguments to and file operation.

Folder security?

I have a folder named upload which is filled with folders of users uploaded files.
Is there any way I can stop people from directly downloading my users files by simply typing the folder names and file name into the address bar?
Example: user Jim's folder is stored at HOST/uploads/jim
user Jim's important file "myimportantfile.txt" is stored at HOST/uploads/jim/myimportantfile.txt
Now, if just anyone types into the address bar: www.HOST.com/uploads/jim/myimportantfile.txt , they will be able to view Jim's important file.
How can I stop this from happening?
Can I write certain attributes when making the directories?
You don't want to have those files in a web-accessible folder. Move them out of the webroot.
Once you do this, you can have a file like download.php to which you pass a file ID and it can then validate it is in fact Jim asking for his files and only then fetch the file and output it to the browser as an attachment. This is the safest/best way for security.
I belive file permissions of a directory +w-r+x will alow directory writes but not reads. In geeky unix terms this is %chmod 733 dirname. The directory ownership would have to be set properly using chown and chgroup. This applies to a unix environment.
You could use an .htaccess file to require a username and password to be entered making each folder a protected folder.
But I think the best way to do it would be to move the uploads folder outside of the webroot so that it's not directly accessible, and then create a script (PHP, ASP, etc) that serves up the requested file after authenticating the user.
The simplest solution is to just add an index.htm file to the folder.
Any visitors will then see this page rather than the index of files.
The page can be blank, or even better, redirect to the domain home page with a redirect.
Sure, you can use basic file/directory permissions in Linux. You can also set the entire tree to be denied by apache.
What platform / webserver software are you running?
Okay, linux:
If the owner of the directory is 'joe', and the group is 'apache', then:
chmod 750 joe
This would give the directory 'joe' permissions which allow the owner (joe) full access, the group (apache) write access (and the ability to enter the directory), and nothing else.
Is this an FTP drop-box?
What are the ownerships/groups like now?

Categories