PHP file permissions, chmod & mkdir not working - php

I created a php function that allows me to add images to a folder within my web application project. Right now it only works when I manually set the permissions of the folder to write enabled. Unfortunately that is not exactly what I need, because when I push my code to my group members with git, they would still have to manually set the permissions of the folder to enable writing as well, in order for my pushed code to work. all my group members and I are each running this project locally via an apache server, and I believe the problem is that apache does not have access to write within any of the folders within the project unless the folders are somehow set to write enable for everyone. I feel like it's not feasible to tell all my group members to change their folder permissions just so my one function can write to a folder.
I am looking for a way to set file permissions within my php code, I have already tried php functions such as chmod and mkdir to set permissions, however it gives me errors saying that I don't have permission to use those functions, which I guess makes sense, but is there a possible work around?

$structure = 'path';
mkdir($structure, 0777, true)
or
$structure = 'path';
mkdir($structure)
chmod($structure, 0777);

<?php $result = mkdir ("/path/to/directory", "0777");
?>
Try this it will working

Try using this (if shell_exec() is allowed):
(list of issues: only works on linux, has a security issue with potential solutions at bottom of post)
<?php
function readFile($file) { return shell_exec("cat $file"); }
function writeFile($file,$cont) { return shell_exec("echo $cont > $file"); }
function makeFile($filename) { return shell_exec("touch $filename"); }
function makeFolder($filename) { return shell_exec("mkdir -pv $filename"); }
// the -pv was used so you could do makeFolder("1/2/3/4")
function appendFile($file,$cont) { fileWrite($file,readFile($file).$cont); }
function appendToTopOfFile($file,$cont) { fileWrite($file,$cont.readFile($file);); }
?>
Use escapeshellcmd or escapeshellargs to escape user input.
ex.
$file=escapeshellcmd($_GET['file']);
echo readFile($file);

Related

PHP: Why is chmod() setting my file/folder to 555 or 444?

I created a web application with a file browser. I'm trying to add a functionality where the user can change the chmod/permissions via an ajax request which is handled via PHP on the back-end.
(Side Note: I'm running my local with WAMP)
So initially, I'm reading the permissions with this
substr(sprintf('%o', fileperms($relativePath)), -4)
to get this format (0777, 0644, etc), if not it returns something like 32726. This info is used to be displayed in the UI for the user to know whats current.
However, when I run the script, I set it to 0777 and it seems to run fine. But then when I read the file again, it returns 0555 or 0444. Anyone know what I'm missing?
Does your web server own the files it is trying to change the permissions on? You can check whether chmod ran correctly or failed by testing its return value. It will return FALSE if the webserver did not have permissions. For more information you can read: http://php.net/manual/en/function.chmod.php
<?php
$is_success = chmod("myfile.pdf", 777);
if($is_sucess) {
echo "success<br />\n";
}
I realized this was not an issue, but rather the chmod command does not work properly on a windows/apache setup.

How to create a folder above the root directory using php

my root dir id
/var/www/html/
i want to create directory at /var/www/
ie /var/www/myfolder
i'm executing create_dir.php
from
/var/www/html/site/create_dir.php
when i execute this program it's unable to create folder.
in log i'm getting permission denide.
update
This is my code
<?php
$os_type=php_uname('s');
$cur_file_path=$_SERVER['PHP_SELF'];
echo "File path:$cur_file_path<br>";
$scount=substr_count($cur_file_path, '/');
echo "/ count:$scount<br>";
$doc_root= $_SERVER['DOCUMENT_ROOT'] ;
echo "doc root:$doc_root<br>";
if($os_type=='Linux')
{
$ds=substr_count("$cur_file_path","/");//directory seperator
echo "Count of /=$ds<br>";
}
if($os_type=='Windows')
{
$ds=substr_count("$cur_file_path","'\'");//directory seperator
}
$path="../";
for($i=1;$i<$scount;$i++)
{
$path.="../";
}
$dir="myfolder";
exec("mkdir ".$dir);
?>
how to solve this.
That is a security problem as it gives read and write access to the world. It may be that your apache user does not have read/write permissions on the directory.
Here's what you do if $os_type=='Linux':
1. Make sure all files are owned by the Apache group and user. In Linux it is the www-data group and user
exec('chown -R www-data:www-data /path/to/webserver/www',$ouput,$result);
2. Next enabled all members of the www-data group to read and write files
exec('chmod -R g+rw /path/to/webserver/www',$ouput,$result);
The php mkdir() function should now work without returning errors. You can also see the error output in $output in case of error.
There is the another way to create directory using ftp:
You can try mkdir with ftp, mkdir works with stream wrappers, so it's ok to write mkdir('ftp://user:pass#server/mydir');
OR
If you have problems with the SAFE MODE Restriction in effect i.e. if you try to create and access to subdirectorys recursive you can use ftp-lib like this.
<?php
DEFINE ('FTP_USER','yourUser');
DEFINE ('FTP_PASS','yourPassword');
/**
* Returns the created directory or false.
*
* #param Directory to create (String)
* #return Created directory or false;
*/
function mkDirFix ($path) {
$path = explode("/",$path);
$conn_id = #ftp_connect("localhost");
if(!$conn_id) {
return false;
}
if (#ftp_login($conn_id, FTP_USER, FTP_PASS)) {
foreach ($path as $dir) {
if(!$dir) {
continue;
}
$currPath.="/".trim($dir);
if(!#ftp_chdir($conn_id,$currPath)) {
if(!#ftp_mkdir($conn_id,$currPath)) {
#ftp_close($conn_id);
return false;
}
#ftp_chmod($conn_id,0777,$currPath);
}
}
}
#ftp_close($conn_id);
return $currPath;
}
?>
Maybe it helps.
The purpose of a "root" directory is to protect the hosting computer from malicious/buggy code that might damage information stored in other parts of the computer. It gives you an area in which you can safely do your thing while explicitly and deliberately preventing you from interfering with any data "above" your root directory. The root is as low as you can go, by design. Any host computer that has a vulnerability that would allow you to access data outside of your assigned space is a host computer begging to be hacked; you won't find many of those, hopefully.
It may be worthwhile to restructure the directories within your root directory to simulate a deeper root than what you are actually restricted to. Otherwise, it is a matter of convincing the system administrator for the host computer to allow you additional access.
In a properly designed and managed system, what you are asking for is intentionally not possible, and running into this particular roadblock is more a sign that you may need to reconsider what you want to do in light of your restrictions. Even if this is being hosted from your own computer and you are the system administrator, it would be wise to examine every possible way you can achieve the goals you hope to achieve without breaking that barrier. ANY means you implement to allow web-controlled code to break that barrier is a vulnerability in your system that someone, somewhere, is looking for an opportunity to exploit.

PHP mkdir not working as expected

I'm working on some PHP that will create a folder every time a request is made to my server. I can't seem to get my syntax proper. If I just used the $date variable it works no problem, however when I add the "clean" folder before it, it won't create the folder.
<?php
$time = $_SERVER['REQUEST_TIME'];
$date = date(Ymd_Hms, $time);
$new = "clean/".$date;
echo $new;
if(!is_dir ($new))
{
mkdir($new);
}
?>
This is scenario is happened to me when I recently configure server
mkdir() function was working and it was giving permission error constantly.
So I found out the solution that folder (in this case clean folder) in which you are creating another folder must have 0777 / 0755 permission and its user:group must be same as that of user and group given in httpd.conf file in apache or httpd folder .
chown -R root:root clean/
when I gave that to that folder it was working like magic.
Please check with this , if all above solutions failed then this will definitely help you.
Put the in ' quotes and give the mkdir() appropriate params and it should work fine:
<?php
$time = $_SERVER['REQUEST_TIME'];
$date = date('Ymd_His', $time);
$new = "clean/".$date;
echo $new;
if(!is_dir ($new))
{
mkdir($new, 0777, true);
}
?>
mode:
The mode is 0777 by default, which means the widest possible access. For more information on modes, read the details on the chmod()
Note: mode is ignored on Windows.
Return Values:
Returns TRUE on success or FALSE on failure.
Note: You don't have to create the folder clean first IF you're using the recursive = true option, Otherwise a folder named clean must be created first.
PHP Manual: mkdir
PS. I've created a directory using this code before posting so it should not
have any problem.

PHP can't write files

I had a Apache HTTP server on CentOS, I installed PHP (yum install php) and then tested a simple script that writes text in a file, so I do
$file = fopen($filename,"w") or die("Failure");
The problem is that it's always a failure, even after I did a chown apache:apache /var/www/html/* or a chmod 777 * in that directory, so anyone knows a way to understand / fix this?
EDIT : So there the problem was thath the directory itself did'nt have the chown
It's hard to say what it is without the actual error message from PHP.
Have a look at this page:
http://www.w3schools.com/php/php_error.asp
Long story short, create and set a custom error handler, like so:
<?php
//error handler function
function customError($errno, $errstr) {
echo "<b>Error:</b> [$errno] $errstr";
}
//set error handler
set_error_handler("customError");
//trigger error
$file = fopen($filename,"w")
?>
In your case, I think that in order for it to be able to create new files in the given directory, you would want to add a '-R' flag to chmod or chown and call it on the directory itself rather than the children -- that way, if PHP has to create the file, it has permissions to do so.
EDIT: Just curious about why this has a downvote -- what is the "egregiously sloppy, no-effort-expended post, or an answer that is clearly and perhaps dangerously incorrect."? I told the OP to examine the error messages and set their permissions in a properly recursive fashion.
Change w mode to w+ - it will allow php to create file if it's not exist.
$file = fopen($filename,"w+") or die("Failure");

Getting around PHP safe mode to write to server. Is it possible?

I have got the following problem since the server has safe mode turned on, and directories are being created under different users:
I upload my script to the server, it shows as belonging to 'user1'. All it is doing is making a new directory when a new user is created so it can store files in it.
New directory is created, but it belongs to 'apache' user.
'user1' and 'apache' are different users; and safe mode is turned on. So the php script cannot write to that newly created directory.
Now I have a problem!
One solution is to turn off safe mode. Also, a coworker suggested that there are settings that can be changed to ensure the directories are under the same user as the script. So I am looking to see if latter can be done.
But I have to ask. Is there a programatical solution for my problem?
I am leaning to a 'no', as safe mode was implemented to solve it at the php level. Also the actual problem may seem like the directory being created under a different user, so a programatic fix might just be a band-aid fix.
I've used this workaround:
instead of php mkdir you can create directories by FTP with proper rights.
function FtpMkdir($path, $newDir) {
$path = 'mainwebsite_html/'.$path;
$server='ftp.myserver.com'; // ftp server
$connection = ftp_connect($server); // connection
// login to ftp server
$user = "user#myserver.com";
$pass = "password";
$result = ftp_login($connection, $user, $pass);
// check if connection was made
if ((!$connection) || (!$result)) {
return false;
exit();
} else {
ftp_chdir($connection, $path); // go to destination dir
if(ftp_mkdir($connection, $newDir)) { // create directory
ftp_site($connection, "CHMOD 777 $newDir") or die("FTP SITE CMD failed.");
return $newDir;
} else {
return false;
}
ftp_close($connection); // close connection
}
}
You might be able to turn safe mode off for a specific directory via a .htaccess file (if on Apache).
php_value safe_mode = Off
You might need to get your hosting provider to make this change for you though in the httpd.conf.
I have had some success with setting the group bit of the upload directory to sticky.
PHP can then create directories inside it and write to it.
http://en.wikipedia.org/wiki/Setuid#setuid_and_setgid_on_directories
chmod g+s directory

Categories