fopen() works, dio_open() doesn't? - php

Seeing some issues running fopen() when dio_open() is working just fine. Here's a test script I wrote to check the issue as it was appearing in a new installation I'm trying to get working.
<?php
echo "Current User: " . get_current_user() . "<br/>";
echo "UID: " . getmyuid() . "<br/>";
echo "GID: " . getmygid() . "<br/>";
echo "<br/>";
$foTest = fopen("test.txt","r");
echo fread($foTest,4);
$fd = dio_open('test.txt', O_RDONLY);
$read = dio_read($fd);
echo $read;
$file = dio_open('test.txt', O_WRONLY | O_CREAT);
?>
The script outputs the following:
Current User: infinitywhack UID: 1004 GID: 1002
test Warning: dio_open(): cannot open file test.txt with flags 0 and
permissions 0: No such file or directory in
/var/www/infinity.whacknet.com/public_html/test.php on line 9
Warning: dio_read() expects parameter 1 to be resource, boolean given
in /var/www/infinity.whacknet.com/public_html/test.php on line 10
Warning: dio_open(): cannot open file test.txt with flags 65 and
permissions 0: Permission denied in
/var/www/infinity.whacknet.com/public_html/test.php on line 12
This shows the user and group (infinitywhack:www) which is correct. The "test" output here is the content of the test.txt file, that is the code that is running with fopen(). The errors are only given by dio functions.
Here are the permissions for both files:
[root#death public_html]# ls -la test.*
-r-xr-xr-x. 1 infinitywhack www 342 May 12 23:36 test.php
-rwxrwxrwx. 1 infinitywhack www 5 May 12 23:06 test.txt
I've been scratching my head all night on this one, there's very little documentation on anything dio from what I have found. Very little saying what is needed here. The only thing I could think of was suExec but there aren't any directives in use that would cause this, although surely those same directives would fail for fopen as well if that were the case?
Any help here would be much appreciated!

I think STLMikey & Ahmet are on the right track.
Try dio_open(__DIR__ . DIRECTORY_SEPARATOR . 'test.txt', ...)
In this source code at least, dio_open makes no attempt to construct an absolute path. The filename parameter is passed to the operating system unchanged.
The No such file or directory & Permission denied errors are coming from the OS, not the dio library. So it seems likely your server is looking for test.txt in the wrong place.

firsty make sure your file is exist.
Also your php file permissions should be 0777 to create file
and you can add a folder to set permission "777" automaticly by this command
$folder=mkdir( "yourdirname", 0777);
And than you should try to understand the problem
$file="test.txt";
//maybe your server cannot find the root
// if it does not solve the problem write root file command
// $file=dirname(__FILE__).DIRECTORY_SEPARATOR."test.txt";
if (file_exists($file)) {
//its ok try to continue
} else {
echo "the text file is not exits !";
}

Related

How to extract Zip archive located under different user directory in ISPConfig 3

I face the problem with extracting the .zip archive located under different user web/ directory. Let me explain: I have 2 websites both written on pure php. First website i use to manage Second. Every client on Second website has his own folder located in root with similar code but different configs. It looks like this:
Second website
...
/var/www/clients/client0/web2/web/client1/...
/var/www/clients/client0/web2/web/client2/...
...
Like you understand owner of this files is user: web2 and group: client0
And First website location:
...
/var/www/clients/client0/web1/web/...
...
Owner of this files is user: web1 and group: client0
What I'm trying to do is to extract zip archive at Second webroot directory while working on my backend on First website when create a new client.
Here is the code i tried(this works perfect on my localhost when user: www-data and group: www-data):
...
if (!file_exists('/var/www/clients/client0/web2/web/' . $_POST['storeid'])) {
$zip = new ZipArchive;
$dir = '/var/www/clients/client0/web2/web/';
$install_dir = $dir . 'backup/';
$res = $zip->open($install_dir . 'client_install.zip');
if ($res === TRUE) {
//Try to execute
$zip->extractTo($dir . $_POST['storeid'] . '/'); //var/www/clients/client0/web2/client2
$zip->close();
//Set permitions on new store folder
chmod_r($dir . $_POST['storeid'], 0755, 0644);
echo "\nExtracted successfully to " . $dir;
die();
} else {
echo "Failed to open zip: " . $dir . "client_install.zip" . " \n";
die();
}
}
...
At the time when i run this code i get message:
Failed to open zip:
/var/www/clients/client0/web2/web/backup/client_install.zip
I know it may be related to user permissions. How can solve this considering keeping same ISPConfig environment and user permissions.
Update:
Here is the error log message:
PHP Warning: ZipArchive::open(): open_basedir restriction in effect.
File(/var/www/clients/client0/web2/web/client1/backup/client_install.zip)
is not within the allowed path(s):(/var/www/clients/client0/web1/web:/var/www/clients/client0/web1/private:/var/www/clients/client0/web1/tmp:/var/www/test.site.com/web:/srv/www/test.site.com/web:/usr/share/php5:/usr/share/php:/tmp:/usr/share/phpmyadmin:/etc/phpmyadmin:/var/lib/phpmyadmin)
in /var/www/clients/client0/web1/web/process.php on line 261.
My question may sound stupid, so I'm sorry in advance. But can a change in the entry in a particular website of open_basedir option affect the performance of the entire server, or the inability of Apache to restart. My question is because my test website is located on a server with production sites. And I would not want to make these changes without initial consultation. So I think I need to add a new path to the open_basedir site parameter. People who know how this option works specifically, please respond to this post. Thanks in advance.

PHP is_writable false for NFS folder although files can be written

Sorry, I'm not sure, if this is the correct forum because I don't know the cause for the issue, I'm facing.
I installed NextCloud on a Raspbian (Stretch 9) and moved the data directory to a mounted NFS folder. When I try to access NextCloud, I got the error message 'Data directory is not writable'.
So I dug a better deeper and could finally isolate the issue to the interaction between PHP7.0 and the NFS:
For some reason, the application can write to the directory but is_writable returns false.
I have created the following PHP script:
<?php
$dirname = '/var/churros/data/nextcloud/';
//$dirname = '/tmp/';
$myfile = fopen($dirname.'newfile.txt', "w") or die("Unable to open file!");
$txt = "John Doe\n";
fwrite($myfile, $txt);
fclose($myfile);
echo nl2br("File ".$dirname."newfile.txt written\n");
if (touch($dirname.'/chkpt.tmp')) {
echo nl2br("touch(".$dirname."/chkpt.tmp) successful\n");
} else {
echo nl2br("touch(".$dirname."/chkpt.tmp) failed\n");
}
if (is_writable($dirname)) {
echo 'Directory '.$dirname.' is writable';
} else {
echo 'Directory '.$dirname.' is not writable';
}
phpinfo();
?>
The result is that
newfile.txt is created in the data directory with the given text (John Doe)
Touch succeeded, i.e. the checkpoint file is created
is_writable returns false Screenshot of 'debug.php' with NFS directory
When I change to directory to a local directory like \tmp everything is fine Screenshot of 'debug.php' with /tmp directory
My NFS is mounted as
192.168.1.100:/volume1/pidata/donut on /var/churros type nfs4 (rw,relatime,vers=4.0,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=192.168.1.103,local_lock=none,addr=192.168.1.100)
and obviously the user mapping and access rights are correct:
namei -l /var/churros/web/nextcloud/
f: /var/churros/web/nextcloud/
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root churros
drwxr-xr-x www-data www-data web
drwxrwxr-x www-data www-data nextcloud
On the command line, as user www-data, I can access the directory and write to it as well.
Finally, SELinux is not installed/enabled on the box.
So: Any idea why PHP is_writable fails on the NFS directory or how I can debug this PHP function?
The issue could be the unix user id is different for user "www-data" for the 2 different systems.
In detail, from the php src, you can see that:
is_writable() is defined at ext/standard/php_filestat.h, which uses:
php_stat header file defined at php_stat()
VCWD_ACCESS() function is used
In turn:
VCWD_ACCESS()
is a convenience wrapper for virtual_access()
virtual_access()
is thread safe wrapper around the access() function that takes
per-thread virtual working directories into account.
Finally, looking access() doc:
The access() function checks the file named by the pathname pointed to by the path argument for accessibility according to the bit pattern contained in amode, using the real user ID in place of the effective user ID and the real group ID in place of the effective group ID.
and also at the access() linux documentation, it states:
access() may not work correctly on NFS file systems with UID mapping enabled, because UID mapping is done on the server and hidden from the client, which checks permissions. Similar problems can occur to FUSE mounts.
Try:
var_dump(stat('nfs-filename'));
and see which uid you get.
Reference:
Similar issue with php session in nfs
Most likely this is is_writable() function's bug.
You may fix this NextCloud issue:
} else if (!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) {
//common hint for all file permissions error messages
$permissionsHint = $l->t('Permissions can usually be fixed by giving the webserver write access to the root directory. See %s.',
[$urlGenerator->linkToDocs('admin-dir_permissions')]);
$errors[] = [
'error' => 'Your data directory is not writable',
'hint' => $permissionsHint
];
AND
/usr/share/webapps/nextcloud/lib/private/Console/Application.php
if ($input->getFirstArgument() !== 'check') {
$errors = \OC_Util::checkServer(\OC::$server->getSystemConfig());
if (!empty($errors)) {
foreach ($errors as $error) {
$output->writeln((string)$error['error']);
$output->writeln((string)$error['hint']);
$output->writeln('');
}
throw new \Exception("Environment not properly prepared.");
}
}
Source #1, Source #2

Why is this PHP code not opening or writing to a file?

I am using PHP to write information to a text file. I have used this code before, and it worked, but in a new project, it is not working.
I think the problem might be a permissions issue. The server is Ubuntu.
$message = "RESULTS = " . $data . "\n";
$fh = fopen("test.txt", 'a'); //open file and create if does not exist
fwrite($fh, "\n\n******* " . date('l, F j, Y (g:i A)') . " *********\n\n"); //Just for spacing in log file
fwrite($fh, $message); //write data
fclose($fh); //close file
When I debug using Netbeans, fopen() returns a boolean value of 0, which I take to means it failed, but I'm not sure what the reason is.
Is there anything wrong with the code above? If not, what permissions settings do I need on the directories or files involved to ensure I'm not getting blocked by a permission setting?
Is there anything else I should be looking for?
Check your directory
add dot-slash (./) at the beginning of your directory
$fh = fopen("./test.txt",'a'); //open file and create if does not exist
In Ubuntu ,
for a single file :
sudo chmod 777 /var/www/your-path/file.txt
for a directory
sudo chmod -R 777 /var/www/your-path

PHP Permissions Denied fopen

I ran into a really bizarre problem. I am trying to perform writing to file using fopen().
This is what I tried in writetofile.php:
$fw = fopen('/test.txt', 'w');
fwrite($fw, 'hello world' . "\r\n");
fclose($fw);
This is the error I keep getting:
Warning: fopen(/test.txt):
failed to open stream: Permission denied in C:\inetpub\wwwroot\writetofile.php on line 41
Warning: fwrite() expects parameter 1 to be resource, boolean given...
I am 100% sure I have permissions to the server. I am the Administrator. Furthermore, I temporarily gave full permissions to everyone. I even tried running the php script locally, directly from the server using localhost. I am not using apache, I am using IIS. I tried restarting IIS after modifying permissions. I am not running php in safe mode.
Any idea on what might be causing this issue?
/test.txt would be a file in the ROOT directory of your filesystem, where user accounts generally do NOT have write privileges (unless you're running this code as root). This is especially true of PHP running under the webserver's user account.
You probably want just test.txt (no leading slash)` which will try to put the file into the script's "current working directory" - usually the same directory the script itself is in.
1- when you rollout website, delete all logs folder names
2- inside the code create folder name as below and create the logs insides
3- write at top of file. (during init the web)
$ClientUserName = gethostbyaddr($_SERVER['REMOTE_ADDR']);
function Data_Log($dataline)
{
global $ClientUserName;
$dir = 'UserInputLog' ;
$fileName = $ClientUserName. '_ServerWebLog.txt';
if(is_dir($dir) === false)
mkdir($dir);
$fileName = $dir. '\\'.$fileName;
$myfile = fopen($fileName, "a") or die("Unable to open file!");
fwrite($myfile, "$dataline\r\n");
fclose($myfile);
}

php unlink. returns no error message and doesn't delete my file

I'm simply trying to delete a file using PHP's unlink. I found an answer on here that told me the best way to do this and I implemented it. Heres the code I am using.
$log_path = realpath($log_file);
if (is_readable($log_path)){
print file_exists($log_path);
$deleted = unlink($log_path);
print "Deleted:".$deleted;
print "Exists:".file_exists($log_path);
}
This just prints 1Deleted:exists:1. I also tried to add in print_r(error_get_last()); under the unlink, but this also returned nothing. All files in the directory are chmod 777 * and there are no other file handlers open. ....what the heck...
The code you used is needlessly cumbersome. A simple call to unlink should do the trick:
unlink( $log_file );
But let's find out what is going wrong. The file exists, because you enter the loop where the print statements are done. The unlink call probably returns false, because the output is "11" and not "111".
So my gut says, it must be a file permissions issue. Are you sure the web user has permission to remove the file? Can you show us the folder permissions, for instance by running ls -la on the command line and pasting the output?
unlink returns either true or false. If you try to print false (print $deleted;), this will print an empty string.
Try this instead:
print $deleted ? "The file was deleted" : "The file was not deleted";
I think you need to check if $log_path is file. Use:
if( is_file( $log_path ) AND is_readable( $log_path ) )
Also, add next line to begin of your script to show all errors and warnings:
ini_set( 'error_reporting', E_ALL );
Its not that your files need to be 0777. It also necessary that your directory can be accessed. What's the mod of your directory?
Next: print $deleted; apparently print false, which is shown as nothing. Try this: echo $deleted ? 1 : 0;
I don't really know the problem, but you should check, if the file is writable and not if it is readable:
<?php
$log_file = "/tmp/test.log";
$log_path = realpath($log_file);
echo "Testing: ". $log_path."\n";
if (is_writable($log_path)) {
echo "exists? ";
echo (file_exists($log_path))?"yes\n":"no\n";
$deleted = unlink($log_path);
echo "deleted? ";
echo ($deleted)?"yes\n":"no\n";
echo "exists? ";
echo (file_exists($log_path))?"yes\n":"no\n";
} else {
echo "file unwritable\n";
}
This code works fine for me (yes, it's also messy ;) ).
file_exists caches the result of the operation, you should call clearstatcache() before the second call
for me it was promises issue solve it with
chown -R www-data:www-data /var/www/
chmod -R g+rwx /var/www/
chmod -R 0755 /var/www/
make sure that php run under user www-datain www.conf e.g I'm using PHP 7.2
nano /etc/php/7.2/fpm/pool.d/www.conf
Change these values :-
listen.owner = www-data
listen.group = www-data
unlink function in my case just returned false everytime. first, thanks to Viktor for this:
Also, add next line to begin of your script to show all errors and warnings: ini_set( 'error_reporting', E_ALL );
It helped me to see warning:
unlink(): http does not allow unlinking in PHP.
And i finally found the solution, described here https://a1websitepro.com/warning-unlink-http-not-allow-unlinking-php/.
The case is that i user http path to the file, but unlink function requires the absolute path to the file from your server.

Categories