Running PhantomJS through exec() - issue with including ~/.fonts - php

I am able to run PhantomJS from both the shell and exec() fine. The server I am using looks for additional fonts in the ~/.fonts/ directory. When those additional fonts are present, from the shell only I am able to take a screenshot with PhantomJS and the expected fonts render well.
> strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font
open("/home/user1/.fonts/TTF/verdana.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/AndaleMo.TTF", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/arial.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/cour.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/georgia.ttf", O_RDONLY) = 11
open("/home/user1/.fonts/TTF/impact.ttf", O_RDONLY) = 11
...
When I try the same command from from exec(), the user fonts directory is not searched.
<?php
exec('strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font');
The ~/.fonts directory is not searched, but a screenshot is written to disk without the proper fonts being rendered.
I understand exec() to run as the Apache user so user fonts won't be used. However,
> whoami
user1
and
<?php
echo exec('whoami');
user1
both show as the same user, so I suspect this is misleading because this works perfectly (fonts and all) in the shell:
php -r "exec('~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg');"
I understand setuid can allow users to exec a program with the permissions of its owner (user1), but this doesn't help. This particular server is a shared server, and su and sudo are disabled so running as a different user is not permitted.
Linux user configurations isn't my area of expertise, but using exec() how to run the PhantomJS command so the user fonts are included?
Research:
Running PhantomJS from PHP with exec() - the problem was with $PATH
PHP + PhantomJS Rasterize - This was a problem with HostGator
exec() and phantomjs issue with absolute paths - One answer suggested running the command as a cron which won't work. Also modifying /etc/sudoers is not possible.

The problem revealed itself when printenv and exec('printenv') were run, respectively
HOME=/home/user1
and
HOME=/home/user1/tmp
This means that even though whoami and exec('whoami') both return user1, something in the shared host configuration set the home directory to /tmp, which is wise to sandbox the script.
The solution is to prepend export HOME=~; (not HOME=~;) to the exec command. i.e.
exec('export HOME=~; strace ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/bin/phantomjs ~/public_html/api/libraries/phantomjs-2.1.1-linux-x86_64/examples/rasterize.js http://v1.jontangerine.com/silo/typography/web-fonts/ ~/tmp/test.jpg | grep font');
This will cause the HOME directory to be set and the user fonts can now be searched.

Related

apache user not able to run sox command

I have a test script which does following:
$a = shell_exec("sox /var/www/html/media/file-all.gsm -r 8000 -c 1 -e signed-integer /var/www/html/wav-files/file-all.wav");
script runs as apache user
source and destination both files and folders have 777 permission
tried changing the group and ownership to apache user too
Still does not work.
Any help appreciated.
Thanks
One possibility is, that the sox command is not in the PATH used by apache user.
Specify the absolute path to sox in your shell_exec() call.

php shell_exec and hg pull

I have written simple php script to help me update site contents when the commit is sent to bitbucket. I have following problem with it.
<?php
$repo_dir = '/var/www/vhosts/my_full_path';
$output = shell_exec('cd '.$repo_dir.' && hg --config auth.rc.prefix=https://bitbucket.org/XXXXX --config auth.rc.username=my_username --config auth.rc.password=my_pass pull -u https://bitbucket.org/XXXXXXX &');
echo $output;
?>
When I type it to web browser it doesn't work. The output of script is:
pulling from https://bitbucket.org/XXXXXXXXXXXXXX
but when I try to execute it under console on the server it works like a charm:
php myscript.php
generates following output:
pulling from https://bitbucket.org/XXXX
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
See the oupt is full and correct! in concole I'm using root user in web browser data-www? Is there any difference in this case?
I have found the solution. I hope it helps someone.
There were two problems:
Permissions to my repo dir
Authentication for user www-data for this repo
The problem occured because web browser doesn't flush warnings and abort messages while executing command shell_exec. If you want to test your script, you have to lgoin to console by SSH (as root for example) then execute script / command as apache user:
sudo -u www-data php /path-to-your-script/script.php
In console you will see all problems which following user generates.

rsync in bash not parsing php-generated --exclude-from file

My rsync bash script isn't parsing my --exclude-from file that's generated via php, but it will if I manually create (as root) the same exact file locally. I've got a web interface on a Xubuntu 12.10 system that writes rsync --exclude-from files locally and then pushes them via rcp to our (CentOS 6) backup boxes that run the rsync script. (Please spare finger wagging about rcp... I know--don't have a choice in this case.)
Webpage writes file:
PHP:
file_put_contents($exclfile, $write_ex_val);
then pushes to the backup box from a local bash script on the webserver with:
Bash:
rcp -p /path/to/file/${servername}_${backupsource}.excl ${server}:/destination/path
I've compared the permissions and ownership of the hand-created file (that works) with the same file that's php/rcp'd (that doesn't), and they're both the same:
Bash:
stat -c '%a' server_backupsource_byhand.excl
644
stat -c '%a' server_backupsource_byphp.excl
644
ls -l server_backupsource_byhand.excl
-rw-r--r-- 1 root root 6 May 11 05:57 server_backupsource_byhand.excl
ls -l server_backupsource_byphp.excl
-rw-r--r-- 1 root root 6 May 11 05:58 server_backupsource_byphp.excl
In case it's relevant, here's my rsync line:
BASH:
rsync -vpaz -v --exclude-from=${exclfile} /mnt/${smbdir} /backup
I suspect php might be writing the file in a different format (e.g. UTF8 instead of ANSI), but I can't figure out how to test this, and have limited knowledge here.
Does anyone have any suggestions on how to get the php/rcp generated file to parse?
Using diff and file I found out that the php-written version wasn't writing the newline. In my variable definition I was using a "." as "$write_ex_val ." Removing this "." let php write the new lines. I also removed the space between the variable and "\n", although I'm not sure if this contributed to the solution. I'd upvote the comment, Earl, but I don't think I have enough rep. Thanks again.

php exec crontab not working

I trying on my local CentOS 5.3 server, when I try to execute below line in my php code from apache webserver
exec("crontab -l", $output, $arg);
The $arg reply 127 (command not found code)
Then I changed below code
exec("/usr/bin/crontab -l", $output, $arg);
The $arg reply 126 (Permission problem code)
Here is my current permission of
/usr/bin/crontab -rwsr-sr-x 1 root root 311288 Mar 15 2007 /usr/bin/crontab.
And there is no /etc/cron.allow and /etc/cron.deny file.
I already turned off Safe_mode in php. Any suggestion to solve this problem?
////////////////////////////////////////////////////////////////////////////////
I note that my problem is related to selinux.
It is working, when I disable selinux
echo 0 > /selinux/enforce
But I don't want to disable selinux, is there any option in selinux to allow crontab from apache?
Add /usr/bin to your shell env path
Add crontab to the same group like of the webserver
Try in php exec("echo $PATH") to see the path variable. You can also look for unsetenv and temporarly disable it
You can look in the php error log for a detailed description of the error but as you said you are familiar with Linux I can't teach you about user right management. A note to the env variable and the path variable it's not always sure the env variable get exported when you run a program. This is maybe the case with your problem. It means either the os is broken or you have to attach the env variable manually to your program. A workaround can be to look where the shell is looking for programs and symlink the program. In your error log it seems that crontab is in the folder /usr/bin. Also this seems not to be a programming question. Ask at server.stackexchange why crontab isn't found. For example my env looks like this:
LC_PAPER=de_DE
LC_ADDRESS=de_DE
LC_MONETARY=de_DE
AF_PIDDIR=/tmp/af-piddir
UPNP_ROOT=upnpav://
SHELL=/bin/sh
TERM=xterm
DISABLE_GATEWAY=1
GTK2_RC_FILES=/etc/hildon/theme/gtk-2.0/gtkrc
TMPDIR=/var/tmp
MMC_SWAP_LOCATION=/media/mmc1
LC_NUMERIC=de_DE
MMC_MOUNTPOINT=/media/mmc1
OLDPWD=/root
HILDON_FM_OBEX_ROOT=obex://
LAUNCHWRAPPER_NICE_KILL=/etc/osso-af-init/nice-kill-launch-wrapper.sh
INTERNAL_MMC_MOUNTPOINT=/home/user/MyDocs
OSSO_VERSION=RX-51_2009SE_20.2010.36-2_PR_MR0
USER=root
LS_COLORS=no=00:fi=00:di=00;36:ln=00;35:pi=40;33:so=01;35:bd=40;32;00:cd=40;32;00:or=01;05;37;41:mi=01;05;37;41:ex=00;33:.cmd=00;32:.exe=00;32:.com=00;32:.btm=00;32:.bat=00;32:.sh=00;32:.csh=00;32:.tar=00;31:.tgz=00;31:.arj=00;31:.taz=00;31:.lzh=00;31:.zip=00;31:.z=00;31:.Z=00;31:.gz=00;31:.bz2=00;31:.bz=00;31:.tz=00;31:.rpm=00;31:.cpio=00;31:.jpg=00;35:.gif=00;35:.bmp=00;35:.xbm=00;35:.xpm=00;35:.png=00;35:.tif=00;35:
LC_TELEPHONE=de_DE
SESSION_BUS_PID_FILE=/tmp/dbus_session_bus.pid.user
OSSO_PRODUCT_HARDWARE=RX-51
STATESAVEDIR=/tmp/osso-appl-states
LAUNCHWRAPPER_NICE_TRYRESTART=/etc/osso-af-init/nice-launch-wrapper-tryrestart.sh
OSSO_PRODUCT_FULL_NAME=Nokia N900
OSSO_PRODUCT_RELEASE_FULL_NAME=Maemo 5
OSSO_PRODUCT_RELEASE_NAME=Maemo 5
MYDOCSDIR=/home/user/MyDocs
PATH=/usr/bin/gnu:/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin
LC_MESSAGES=de_DE
OSSO_PRODUCT_SHORT_NAME=Nokia N900
SESSION_BUS_ADDRESS_FILE=/tmp/session_bus_address.user
LC_IDENTIFICATION=de_DE
PWD=/home/user/MyDocs
EDITOR=/usr/bin/nano -w -c
LANG=de_DE
ERR=0
LC_MEASUREMENT=de_DE
PS1=[\033[1;36m][[\033[0;36m]\u\h[\033[0;37m]:\w[\033[1;36m]][\033[m]$ [\033[0;37;00m]
ILLEGAL_FAT_CHARS=/:*?<>|
OSSO_PRODUCT_KEYBOARD=German
AF_DEFINES_SOURCED=1
SHLVL=1
HOME=/root
SDL_AUDIODRIVER=pulse
OSSO_SWAP=/home/user/MyDocs
OSSO_PRODUCT_RELEASE_VERSION=20.2010.36-2
LS_OPTIONS=--color
LAUNCHWRAPPER_TRYRESTART=/etc/osso-af-init/launch-wrapper-tryrestart.sh
OSSO_PRODUCT_NAME=N900
AF_INIT_DIR=/etc/osso-af-init
MMC_DEVICE_FILE=/dev/mmcblk0p1
LOGNAME=root
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-eCbOI2qrVP,guid=cd1dea104334a338a9007b9700000014
LAUNCHWRAPPER=/etc/osso-af-init/launch-wrapper.sh
OSSO_PRODUCT_WLAN_CHANNEL=fcc/us
MAX_FILENAME_LENGTH=255
DISPLAY=:0.0
LAUNCHWRAPPER_NICE=/etc/osso-af-init/nice-launch-wrapper.sh
LC_TIME=de_DE
INTERNAL_MMC_SWAP_LOCATION=/home/user/MyDocs
LC_NAME=de_DE
OSSO_PRODUCT_REGION=Germany
_=/usr/bin/gnu/env
Just type env in the prompt.

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