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")
Related
I want to allow users to execute a bash script that contains sensitive data. Thus, I don't want them to have reading permissions. A 'direct' solution seems to be impossible, but I may have found a workaround in the expect man page:
Create the Expect script (that contains the secret data) as usual.
Make its permissions be 750 (-rwxr-x---) and owned by a trusted group,
i.e., a group which is allowed to read it. If necessary, create a new
group for this purpose. Next, create a /bin/sh script with permissions
2751 (-rwxr-s--x) owned by the same group as before.
I've tried to replicate this as follows:
In a folder, I have two scripts:
script.sh:
#!/bin/sh
echo "targetscript echo"
runscript.sh:
#!/bin/sh
echo "runscript echo"
groups
./script.sh
I gave them the rights as suggested in the man page:
groupadd scriptrunner
chown {myusername}:scriptrunner runscript.sh
chmod 2751 runscript.sh
chown root:scriptrunner script.sh
chmod 750 script.sh
The output of ls -l appears to be alright:
-rwxr-s--x. 1 {myusername} scriptrunner 51 Aug 25 13:04 runscript.sh
-rwxr-x---. 1 root scriptrunner 35 Aug 25 13:01 script.sh
However, when I run ./runscript.sh without root, I get the following error:
runscript echo
{myusername} wheel
./runscript.sh: line 4: ./script.sh: Permission denied
I don't know what went wrong. Can anyone help me?
I'll go back to the root problem as I think it's easier to solve without the expect hack.
So, what you need is having the execute permission on your script but not the reading permission. That is only possible for binaries (i.e. not interpreted scripts)- see details here https://unix.stackexchange.com/questions/34202/can-a-script-be-executable-but-not-readable
So maybe you'll be better off by first compiling your bash script into a binary (with shc - see here https://unix.stackexchange.com/questions/64762/how-to-convert-a-shell-script-into-a-binary-executable) and then set the execute only permission on the binary. Afterwards your users should be able to execute (but not read) the binary.
I'm working with Sximo that has the option to add modules through it's web interface. When you add a module it writes php files that has the functionality for that module.
I need to edit that php files with my own user, but obviously that files are written by www-data user.
I already set APACHE_RUN_GROUP=web in apache envars in order to uses the group web where my user is part of.
So the files results in:
-rw-r--r-- 1 www-data web 5621 abr 11 12:43 sximo/modules/Mynewmodule.php
My question is, if there is a way to say to apache that write the files with +w access to the group?
-rw-rw-r-- 1 www-data web 5621 abr 11 12:43 sximo/modules/Mynewmodule.php
Try to change the owner of the target directory to the owner of apache.
Use
chown -R group:user target
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.
I'm trying to work out why I need x permissions for others on a directory to read the stats of the files within it.
this is my folder:
4 drw-r--r-x 2 root root 4.0k Dec 7 17:40 file_host
When the permissions are set so x is assigned to others I can read the files filemtime etc without issue. If I remove the x then I get:
Warning: filemtime(): Stat failed for /file_host/file1234.zip (errno=13 - Permission denied)
The permission on the files in the directory are:
9684 -rw-r--r-- 1 root root 9.4M Dec 7 17:40 file1234.zip
As soon as I add x to the folder it all works. The web user isn't root and doesn't have any root privileges.
Why do you need x to execute the file to read it's values ?
Any way around this ?
Thanks
The execute x bit is what allows a user to descend into a directory. The way your folder is owned, you require execute bit on the other portion of the permissions to allow the www-data / apache user to descend into the directory. If you run chown root:www-data and then remove the x bit on the other portion you will notice this will continue to work without giving all other users on the OS access to the directory.
Is there a way to set php running under apache to create folders with the folder owned by the owner of the program that creates it instead of being owned by apache?
Using word press it creates new folders to upload into but these are owned by apache.apache and not by the site that they are running in. This also happens using ostickets. For now we have to SSH into the server and chmod the folder, but it would seem there would be a setting somewhere to override the ownership outside of any program that does it.
Safe_mode is turn on on your server. The function mkdir() creates folder with owner ("apache", "none", ..) that different of the current script owner. And scripts couldn't upload (move, copy) files into that folder with another owner (that is not like current script owner).
Disable safe_mode and that would be work.
See http://php.net/manual/en/features.safe-mode.php for details.
P.S. With enable safe_mode you can't use chmod() function in php.
Another way is to put the apache user and the "customer users" in a new group. Additional the directory should use the sticky bit SGID so each new file got the group assignment to this new group. This way the webserver and the "customer users" can work with the files without any problems
[17:57] progman#proglap /tmp/test $ ls -al /tmp/test
total 9
drwxrwsr-x 2 root users 48 Apr 1 17:55 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
As you see the directory got the stick bit SGID and the owner is the "users" group in which I (progman) am. No if another user adds a file the group automatically get set to this group
[17:55] proglap ~ # touch /tmp/test/x
This is executed from root. Now we get:
[17:57] progman#proglap /tmp/test $ ls -la /tmp/test
total 9
drwxrwsr-x 2 root users 72 Apr 1 17:59 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
-rw-r--r-- 1 root users 0 Apr 1 17:59 x
As you see the added file is from root, but the group is set to users and this way I can remove it
[18:00] progman#proglap /tmp/test $ rm x
rm: remove write-protected regular empty file `x'? y
[18:01] progman#proglap /tmp/test $ ls -la /tmp/test
total 9
drwxrwsr-x 2 root users 48 Apr 1 18:01 .
drwxrwxrwt 36 root root 9264 Apr 1 17:53 ..
Keep in mind that you still need to change the chmod if you want to edit the file as rw-r--r-- is just group read access. But changing the chmod, maybe even working with umask, is better than dealing with root-access and using chown.
Not directly, no. You can't "give away" ownership of a file to another user, unless you're root. You could investigate using the "AssignUserID" apache directive to force that particular vhost to run as a particular user/group. With that Apache/PHP would create any files with the appropriate ownership
Check out PHP chown() function