After tar extract, Changing Permissions - php

Just a Question Regarding unix and PHP today.
What I am doing on my PHP is using the Unix system to untar a tarred file.
exec("tar -xzf foo.tar.gz");
Generally everything works fine until I run into this particular foo.tar.gz, which has a file system as follows:
Applications/
Library/
Systems/
After running the tar command, it seems that the file permissions get changed to 644 (instead of 755).
This causes Permission denied (errno 13) and therefore disabling most of my code. (I'm guessing from lack of privileges)
Any way I can stop this tar command completely ruining my permissions?
Thanks.
Oh and this seems to only happen when I have a foo.tar.gz file that Has this particular file system. Anything else and I'm good.

If you want to keep the permissions on files then you have to add the -p (or --preserve-permissions or --same-permissions) switch when extracting the tarball. From the tar man pages :
--preserve-permissions
--same-permissions
-p
When `tar' is extracting an archive, it normally subtracts the
users' umask from the permissions specified in the archive and
uses that number as the permissions to create the destination
file. Specifying this option instructs `tar' that it should use
the permissions directly from the archive.
So PHP code should be :
exec("tar -xzfp foo.tar.gz");

Edit: --delay-directory-restore solved the problem below about being unable to untar a file. The permissions of pwd are still altered, so the problem of the original poster might not be solved.
Not really an answer, but a way to reproduce the error.
First create some files and directories. Remove write access to the directories:
mkdir hello
mkdir hello/world
echo "bar" > hello/world/foo.txt
chmod -w hello/world
chmod -w hello
Next, create the tar file from within the directory, preserving permissions.
cd hello
tar -cpf ../hw.tar --no-recursion ./ world world/foo.txt
cd ..
Listing the archive:
tar -tvf hw.tar
# dr-xr-xr-x ./
# dr-xr-xr-x world/
# -rw-r--r-- world/foo.txt
So far, I've been unable to untar the archive as a normal user due to the "Permission denied"-error. The archive can't be untarred naively. The permissions of the local directory change as well.
mkdir untar
cd untar
ls -ld .
# drwxr-xr-x ./
tar -xvf ../hw.tar
# ./
# world/
# tar: world: Cannot mkdir: Permission denied
# world/foo.txt
# tar: world/foo.txt: Cannot open: No such file or directory
# tar: Exiting with failure status due to previous errors
ls -ld .
# dr-xr-xr-x ./
Experimenting with umask and/or -p did not help. However, adding --delay-directory-restore does help untarring:
tar -xv --delay-directory-restore -f ../hw.tar
# ./
# world/
# world/foo.txt
ls -ld .
# dr-xr-xr-x ./
chmod +w .
It is also possible to untar the file as root. What suprised me most is that tar apparently can change the permissions of pwd, which is still unsolved.
By the way, I originally got into this problem by creating a tarball for / with
tar -cvpzf backup.tar.gz --exclude=/backup.tar.gz --one-file-system /
as root (pwd=/) and untarring it as a normal user to create a linux container.

Related

PHP Docker write to stderr through file

Is it possible to redirect a plain text log file to stderr within a Docker container that is writable by PHP?
I have a PHP application that is writing to a file and we're trying to move it into a Docker container without changing any code. I've tried symlinking but this results in permissions errors.
Not sure what type of symlinking you tried but you should be able to do this with something like
RUN ln -sf /dev/stderr /path/to/your/text.log
In your Dockerfile (where the text.log path is the one inside the container).
I ended up finding this solution which uses a fifopipe to pipe the data into stdout.
# Allow `nobody` user to write to /dev/stderr
mkfifo -m 600 /tmp/logpipe
chown nobody:nobody /tmp/logpipe
cat <> /tmp/logpipe 1>&2 &
https://github.com/moby/moby/issues/6880#issuecomment-344114520

Permission denied when logging on /var/log from a php script

I found my crontab scripts do not work as expected because they cannot write on /var/log. I tried executing command:
sudo /usr/bin/php /var/www/html/iPhone/inarrivo/php/rome/process.php >>
/var/log/romeLoading.log 2>&1
by hand and got:
-bash: /var/log/romeLoading.log: Permission Denied
/var/log permissions are:
drwxr-xr-x. 13 root root 4096 15 ago 16.20 .
If I conversely execute:
sudo touch /var/log/loadRome.log
I get no error whatsoever.
What could be the issue?
Please note Apache is not at stake: I am calling those scripts from the root crontab and from the shell with sudo as a test.
best guess: the user running the shell doesn't have write access to /var/log/romeLoading.log , and the stdout redirect (>>) is redirected by the shell user, not the sudo user, thus the access denied on >> , but not on sudo touch. maybe try
sudo sh -c '/usr/bin/php /var/www/html/iPhone/inarrivo/php/rome/process.php >> /var/log/romeLoading.log 2>&1'
that should run sh as root, and have the root-sh do the redirect with root permissions. untested though.
and next time you want to post permissions for debugging, post the namei -l path/to/file output, it gives much more info than stating the single file itself when debugging permission issues, as the issue can be higher up than the file itself, like the folder its in, or the folder that the folder it's in, is in, etc~ and namei gives you, recursively, detailed permission information on all of them.
It's a permissions issue as the log file belongs to root user and apache runs off www-data. Try chown www-data:www-data /var/log/loadRome.log.

Running git commands from within a PHP script

I have a file upload form and after the file uploads I want to push the files up to GitHub by running:
git add .
git commit -m "some message"
git push origin master
How do I go about this? I've seen examples of using exec() but that makes me nervous.
shell_exec('cd /var/www/vhost/xxx.com/httpdocs/clients/portal/upoads/54 && /usr/bin/git add -A');
shell_exec('cd /var/www/vhost/xxx.com/httpdocs/clients/portal/upoads/54 && /usr/bin/git commit -m "something 1"');
shell_exec('cd /var/www/vhost/xxx.com/httpdocs/clients/portal/upoads/54 && /usr/bin/git push origin master');
Those commands don't error but don't work either. Do I need to grant access to the apache user to use the ssh key?
i guess is permission problems, you can use exec() , and get the error info by $output
exec($your_command.' 2>&1', $output, $return_var);
var_dump($output);
Do I need to grant access to the apache user to use the ssh key?
Yes.
This means you have to copy the key somewhere that the apache user can read it. SSH won't work unless the key file is readable by the user only (i.e. 0600 permissions on the key file).
Copy the key like:
mkdir -p --mode=0700 ~apache/.ssh
cp /my/id_rsa ~apache/.ssh/id_rsa
chown -R apache:apache ~apache/.ssh/id_rsa
chmod 0600 ~apache/.ssh/id_rsa
Also, you don't need to cd every time you want to run the command. Use GIT_DIR:
putenv('GIT_DIR=/path/to/git/repo')
shell_exec('git commit ...')
I solved it. I ran all of this as root user.
Inside my PHP script I ran
exec("whoami");
to get the user that is running that script. Then I ran
cat /etc/passwd
to get the home directory for that user (/var/www/vhost/mydomain.com)
I noticed that on my web server (Centos 7) that all my web files were chown'd as opcode:psacln so I created a .ssh directory inside opcode's home folder:
mkdir -p --mode=0700 /var/www/vhost/mydomain.com/.ssh
cd (back to root)
cp .ssh/id_rsa /var/www/vhost/mydomain.com/.ssh/id_rsa
chown -R opcode:psacln /var/www/vhost/mydomain.com/.ssh/id_rsa
chmod 0600 /var/www/vhost/mydomain.com/.ssh/id_rsa
The thing I was missing was that I had to also move my known_hosts file over, since the script I was using wasn't adding to it.
cp .ssh/known_hosts /var/www/vhost/mydomain.com/.ssh/known_hosts
chmod 0600 /var/www/vhost/mydomain.com/.ssh/known_hosts
Of course, I had to login to my server at the command line and do an initial commit to the repo in order to get it added to my known_hosts file, before I copied it over. Hope this helps someone.

Linux - Centos : Giving nginx chmod access

Alright so I cannot for the life of me get rid of this error :
Warning!
ErrorException [ Warning ]: chmod(): Operation not permitted
COREPATH/classes/finder.php # line 511:
510: {
511: chmod($dir.$file, \Config::get('file.chmod.files', 0666));
512: }
Here is my setup for permissions :
(775) : drwxrwxr-x myuser:nginx
Groups :
nginx:x:499:myuser,nginx
PHP-FPM Config
user = nginx
group = nginx
So this works for creating / editing files ect. and that all works fine.
How can I get this to work correctly?
As root, try:
chown nginx:nginx /your/directory/to/fuel/ -R
Also don't forget to run inside the FuelPHP directory:
php oil r install
in order to make the necessary directories of FuelPHP writable
It was because nginx had created a file, it has to be the owner.
PHP runs as www-user (or similar) - check your permissions against that.
What is you full path to file you are chmod'ing ?
For example if its: /var/www/website/fuel/app/tmp/myfile.jpeg
try checking the permissions for:
ls -la /var/www/website/fuel/app/tmp/myfile.jpeg
ls -la /var/www/website/fuel/app/tmp
ls -la /var/www/website/fuel/app
ls -la /var/www/website/fuel
ls -la /var/www/website
ls -la /var/www
And compare them
If think some of parent directories are just not 'writeable by others'

PHP fopen can't create a file

I have a function in PHP language to create an xml file when requested.
if(($file= fopen("./include/catalogo.xml", "w"))==false){echo 'non creo il file'; return false;}
"catalogo.xml" can't be created, permission denied. I know I should try to change permissions, but how can do this if the file doesn't exist? Or, are there things that I ignored?
I think you might be ignoring the permissions of the directory (./include).
I'm assuming you are running this PHP via a web-server and on Linux (like Apache for example) - in which case the user account that is trying to create the file will be 'apache' or 'www-data' (or whatever user your webserver is running under).
On your server - have a look at the permissions of ./include - you need to do one of two things:
a) make ./include world writable (so the 'apache' user can now create a file inside of it).
b) change the owner or group of the ./include to 'apache' so it can create a file inside of it.
Your PHP is fine - it's the permissions of the folder it is trying to create the file inside of that is not.
You have to change the ownership of the directory "include" and set it to the web server's user and set the permission to a reasonable value:
$ sudo chow www-data include
$ sudo chmod 755 include
If you don't know which user your web-server is running by you can open the include dir permissions world-wide:
$ sudo chmod 1777 include
after create the creation of catalogo.xml you check the include diretory:
$ sudo ls -al include
-rwxr-xr-x 1 http web 4096 May 5 15:37 catalogo-xml
Now you can change the ownership of the directory "include" and set it to the web server's user (http) and reset the permission to a reasonable value:
$ sudo chow http include
$ sudo chmod 755 include
See also the manual of chmod, chown and ls:
$ man chmod
$ man chown
$ man ls
If you use the terminal and go to the parent of folder your file will be created in, which is the parent of the include folder and type in the command:
chmod 777 include
This should change the permissions of this folder so you won't receive the permission denied error anymore. If you do try this command:
chmod -R 777 include

Categories