Php script not running with www-data cron - php

after a week of trying i dont know what else to do.
I have a simple php script that is on my webserver called getpoem.php
The script opens up a website pulls its content and saves it to a poem.txt on the server
<?php
//File to extract the Poem of the day
$homepage = file_get_contents('http://SomeWebsite.com/today.php');
$poemALL = substr($homepage,strpos($homepage,"<p>"),strlen($homepage));
.
. // extracting the poem and saving it to $poemFinish
.
file_put_contents("poem.txt", $poemFinish); ?>
so this is a fairly simple script (it works fine if i manually execute it). This script should be executed with the www-data user with its cron so i opend up cron with this command and entered the command it should run
sudo crontab -u www-data -e
0 3 * * * php /var/www/html/getpoem.php
to avoid any permission problems i gave the getpoem.php and poem.txt rwx rights like this (i know i should change it when its live but this is just to test)
-rwxrwxrwx 1 www-data www-data 1189 Aug 17 15:07 getpoem.php
-rwxrwxrwx 1 www-data www-data 1335 Aug 17 15:07 poem.txt
So this is the setup, but it will not execute.
What i did so far changing the "php" to /usr/bin/php to secure that cron know what php is.
Next thing i did was making shure that cron was running so i changed the cronjob to
2 * * * */usr/bin/php /var/www/html/getpoem.php | > /var/www/html/test.txt
wich again did nothing .... so i changed it to
2 * * * */usr/bin/php /var/www/html/getpoem.php | > /tmp/test.txt
that did not run the php file but created a empty (-.-") file called test.txt in my tmp dir.
So i think the problem must be someware in the acces rights of my www-data user. It's just very wierd because all my webcontent (php files, webapp usw.) are also owned by the www-data user and they run smoothly.
Do i need to grand extra privileges for the cron of www-data ?

When running php from cron, your working directory usually isn't the directory the file is located in. When writing a file, it might try to write the file poem.txt relative to / which usually isn't writable.
So you either set the working directory or you should use "absolute" paths. So for example:
file_put_contents(__DIR__.'/poem.txt');
where __DIR__ is a magic constant that contains the directory where the current file is in.

Related

Magento 1 Cache folder is not accessible when using shell command

I'm having a problem with getting a shell command to clear a specific product cache because the permissions in the cache folder are strictly restricted to www-data. For example, folder /var/cache/mage--a files are like these:
-rw------- 1 www-data www-data 7646 Mar 4 11:20 mage---c54_PRODUCT_CACHE_123
-rw------- 1 www-data www-data 184 Mar 4 11:20 mage---internal-metadatas---c54_PRODUCT_CACHE_123
So when the shell command runs, it calls Mage::app()->cleanCache('PRODUCT_CACHE_123'), which triggers down to _fileGetContents function defined in lib/Zend/Cache/Backend/File.php and it's unable to open the meta file in /var/cache/mage--a due to the permissions listed above.
Does anyone have a suggested fix for this?
I ended up using Redis for caches instead. This helped solve the problem as i don't need to set up file permissions for the cache folder anymore.

How to run a python script using PHP and create a file?

I am trying a POC running a python script in a back-end implemented in PHP. The web server is Apache in a Docker container.
This is the PHP code:
$command = escapeshellcmd('/usr/local/test/script.py');
$output = shell_exec($command);
echo $output;
When I execute the python script using the back-end we are getting a permission denied error for creating the file.
My python script:
#!/usr/bin/env python
file = open("/tmp/testfile.txt","w+")
file.write("Hello World")
file.close()
This is the error I'm getting:
IOError: [Errno 13] Permission denied: 'testfile.txt'
For the directory im working with the permissions are as follows,
drwxrwsr-x 2 1001 www-data 4096 May 8 05:35 .
drwxrwxr-x 3 1001 1001 4096 May 3 08:49 ..
Any thoughts on this? How do I overcome this problem?
To start is is incredibly bad practice to have relative paths in any scripting environment. Start by rewriting your code to use a full path such as /usr/local/test/script.py and /tmp/testfile.txt. My guess is your script is attempting to write to a different spot than you think it is.
When you know exactly where the files are being written go to the directory and run ls -la and check the permissions on the directory. You want it to be writeable by the same user or group as the web server runs.
Looking at the permissions you have shown you don't have the user able to write to the directory, just everyone and the group. You need to add user write permissions - chmod u+w /tmp will do the job.
I believe the problem is that you are trying to write to an existing file in the /tmp/ directory. Typically /tmp/ will have the sticky permission bit set. That means that only the owner of a file has permission to write or delete it. Group write permissions on files do not matter if the sticky bit is set on the parent directory.
So if this is the contents of your /tmp
$ ls -al /tmp
drwxrwxrwt 5 root root 760 Apr 30 12:00 .
drwxr-xr-x 21 root root 4096 Apr 30 12:00 ..
-rw-rw---- 2 1001 www-data 80 May 8 12:00 testfile.txt
We might assume that users in the group www-data should be able to write to testfile.txt. But that is not the case, since . (the /tmp/ directory itself) has the sticky bit set (the t in the permissions section indicates this).
The reason why the sticky bit is set here is that everyone should be able to write files there, but not have to worry that other users might modify our temporary files.
To avoid permission errors, you can use the standard library tempfile module. This code will create a unique filename such as testfile.JCDxK2.txt, so it doesn't matter if testfile.txt already exists.
#!/usr/bin/env python
import tempfile
with tempfile.NamedTemporaryFile(
mode='w',
prefix='testfile.',
suffix='.txt',
delete=False,
) as file:
file.write("Hello World")

Cron job running, but not overwriting file

I have the following set as a cron job:
*/1 * * * * /usr/bin/php /var/www/html/recalls/php/savesjson.php
I checked the status and I get this back.
Mar 10 16:29:01 big-hoster CRON[30417]: (root) CMD (/usr/bin/php /var/www/html/recalls/php/savesjson.php)
Mar 10 16:29:02 big-hoster CRON[30416]: pam_unix(cron:session): session closed for user root
The savesjson.php file should execute and basically save a new JSON file (current.json) in the same directory. If I just run this file (by going to the URL), it works perfectly. However, my cron isn't actually updating the current.json file.
current.json has permissions as follows:
-rwxr--r-- 1 root root 0 Mar 10 16:17 /var/www/html/recalls/php/current.json
savesjson.php has permissions as follows:
-rwxr-xr-x 1 www-data www-data 213 Mar 8 14:11 /var/www/html/recalls/php/savesjson.php
What am I missing here?
UPDATE: If I try to execute from the CLI, like so:
# /usr/bin/php /var/www/html/recalls/php/savesjson.php
It appears to execute, but the script doesn't do what it's supposed to (create new file) and there are no errors in my PHP logs. However, the PHP does work if I go directly to the URL (example.com/php/savesjson.php).

PHP script running at Apache and Linux doesn't create file

I need some help as my script doesn't create a file. I want to run this script at cronjob. I am using Debian Linux with PHP and Apache.
My script is locate at /var/www/myapplication folder. I want to create / write a file at /var/www/myapplication/testfolder.
The commands I use in the php script is:
echo `whoami`;
exec ('whatever >> testfolder/testing.txt');
Folder rights:
drwxrwxrwx 2 www-data www-data 4096 Jul 27 09:55 testfolder
When I run the script directly from browser (http://127.0.0.1/myscript.php)
it doesn't create the file (testing.txt)
echo whoami says: www-data
When I run the script from the server with root rights (su):
php -q /var/www/myapplication/myscript.php >>log3.txt
it creates the file (testing.txt)
echo whoami says: root
log3.txt is created at /var/www/myapplication folder
When I run the script from crontab:
/usr/bin/php -q /var/www/myapplication/myscript.php >>log3.txt
it doesn't create the file (testing.txt)
echo whoami says: root
log3.txt is created at /root folder
Why isn't testing.txt created my I run my script from crontab as a cronjob ?
You shouldn't be executing operating system commands directly, there are already functions and objects avaliable in PHP for writing and read files. As well, you shouldn't be giving them permission to be writing files to /. Even though you're running it from localhost, if you ever expose the service you're allowing public users to run operating system commands.
You also mention in your comment that you want to redirect the output of 'whatever' to a file, but I still don't see why you couldn't do this with the PHP provided functions.
Regardless, to answer the original question when you run the script via localhost you're accessing it via Apache which means the user www-data is running the PHP script. When you access it via your cronjob you're calling PHP from the commandline and another user is accessing the service.
You can see the error that is being returned from attempting to write to the file by logging in with the user running the cronjob and using echo exec(...).

SSH backup via PHP problem

I am trying to backup all the files on our server using some SSH commands via PHP and I have a script working to some extent.
The problem is that only some of the folders actually contain any files but the folder structure seems to be correct though.
This is the script I am using:
<?php
$output = `cd /
ls -al
tar -cf /home/b/a/backup/web/public_html/archive.tar home/*`;
echo "<pre>$output</pre>";
?>
I cant even view the files via SSH commands, an example of this is the test account. If I use the following command I am unable to view the website files.
<?php
$output = `cd /home/t/e/test/
ls -alRh`;
echo "<pre>$output</pre>";
?>
But if I use the same commands on the a different account I am able to see and download of the website files.
Is this a permission problem or am I missing something in my script?
Thanks
ls -l / | grep home
the output will be like this:
lrwxr-xr-x 1 root wheel 8 Mar 30 14:13 home -> usr/home
In my case, the owner is root, and the root user its primary group is wheel, so now we add www-data user to wheel group so he can list files in there:
usermod -a -G wheel www-data
You can download some files because they located in directory owned by www-data user, and when you can't, www-data has no permission in that.
I think it permission problem, try to give apache user(or what you set it) permission to read /home/* directory's.
To find the user name that used by apache service run this:
For linux:
egrep -iw --color=auto 'user|group' /etc/httpd/conf/httpd.conf
For FreeBSD:
egrep -iw --color=auto '^user|^group' /usr/local/etc/apache22/httpd.conf
My guess is that PHP is running in a chroot.
If you just want to execute a backup, consider doing it in a different language. Especially if it is just a sequence of UNIX commands, write a shell script. Perhaps more details on what this script will be used for and who is providing and maintaining your hosting will be useful.

Categories