currently I am trying to set up a virtual machine for development for a client. Three SVN repositories with PHP code have to be combined in one folder (I know it's ugly, but that's how they roll). I Googled a little and found mhddfs. So I checked out the three repositories in a folder called branches:
branches/branch1
branches/branch2
branches/branch3
I mounted the three branches with mhddfs at /mnt/dev. At the filesystem level, everything works as expected, so ls correctly displays the contents of all three folders (they are disjoint). However, trying to fire up the document root with Apache results in a 403 Forbidden error. I tried other locations than /mnt/dev as well, leading to no difference.
[Mon Feb 06 17:44:41 2012] [error] [client 192.168.56.1]
(13)Permission denied: access to / denied
When I do not mount the three folders but just put an index.php file into /mnt/dev, everything works as expected. Am I missing something?
Thanks for your help in advance.
EDIT: Some more data on the problem: When I create two directories, that are world-accessible ...
root#devbox:/tmp > ls -lha
drwxrwxrwt 6 root root 4,0K 6. Feb 20:11 .
drwxr-xr-x 21 root root 4,0K 6. Feb 10:07 ..
drwxrwxrwx 2 www-data vboxsf 4,0K 6. Feb 20:11 test1 # includes index.htm
drwxrwxrwx 2 www-data vboxsf 4,0K 6. Feb 20:13 test2 # includes index2.htm
... and mount them via mhddfs ...
mhddfs /tmp/test1,/tmp/test2 /mnt/dev
mhddfs: directory '/tmp/test1' added to list
mhddfs: directory '/tmp/test2' added to list
mhddfs: mount to: /mnt/dev
mhddfs: move size limit 4294967296 bytes
... ls behaves correctly ...
root#devbox:/tmp > ls -lh /mnt/dev/
insgesamt 8,0K
-rwxrwxrwx 1 www-data vboxsf 12 6. Feb 20:11 index2.htm
-rwxrwxrwx 1 www-data vboxsf 11 6. Feb 20:11 index.htm
... while Apache (user: www-data, group: vboxsf) doesn't and terminates with the 403 error stated above. However, if I unmount the folders and just put an index.htm in /mnt/dev, everything works as expected as Apache can read the file.
Any ideas?
All the best,
Martin
I encountered the same problem on Linux.
Following the steps below, I was able to solve it.
[STEPS]
Enable 'user_allow_other' in /etc/fuse.conf
Use mhddfs with '-o allow_other' option ex. mhddfs -o allow_other
/dir1,/dir2 /path/to/mount
Related
I'm having permissions problems when running the following PHP script as root:
#!/usr/bin/php
<?php
$ph = proc_open('whoami', [['pipe','r'],['pipe','w'],['file','/tmp/foo.bar', 'w']], $fds);
if ($ph) {
echo 'command output: ' . stream_get_contents($fds[1]);
proc_close($ph);
} else {
echo 'proc_open failed' . PHP_EOL;
}
The script itself runs fine if /tmp/foo.bar doesn't exist, or is owned by root. But if ownership is changed to another user, proc_open will fail regardless of permissions on the file.
SELinux is disabled, and we are not using ACLs. I'm using PHP 7.4.33 (I know it's old and unsupported, but it's a requirement for FreePBX) on Alma Linux 9.1.
Output:
$ ./test.php
command output: root
$ ls -lah /tmp/
total 12K
drwxrwxrwt. 18 root root 4.0K Dec 14 16:57 .
dr-xr-xr-x. 18 root root 4.0K Dec 14 16:48 ..
-rw-r--r-- 1 root root 0 Dec 14 16:57 foo.bar
$ chown admin /tmp/foo.bar
$ ./test.php
proc_open failed
$ chmod 777 /tmp/foo.bar
$ ./test.php
proc_open failed
$ ls -lah /tmp/
total 12K
drwxrwxrwt. 18 root root 4.0K Dec 14 16:57 .
dr-xr-xr-x. 18 root root 4.0K Dec 14 16:48 ..
-rwxrwxrwx 1 admin root 0 Dec 14 16:57 foo.bar
$ tail -2 /var/log/php.log
[14-Dec-2022 16:57:17 America/Toronto] PHP Warning: proc_open(/tmp/foo.bar): failed to open stream: Permission denied in /test.php on line 3
[14-Dec-2022 16:57:28 America/Toronto] PHP Warning: proc_open(/tmp/foo.bar): failed to open stream: Permission denied in /test.php on line 3
Even disregarding the fact that I'm root, group permissions should allow me full access to the file. So what's going on?
This is due to the permissions on the /tmp directory. When PHP tries to open the file for writing, it gets the EACCES error. From the documentation of open(2):
EACCES
Where O_CREAT is specified, the protected_fifos or protected_regular sysctl is enabled, the file already exists and is a FIFO or regular file, the owner of the file is neither the current user nor the owner of the containing directory, and the containing directory is both world- or group-writable and sticky. For details, see the descriptions of /proc/sys/fs/protected_fifos and /proc/sys/fs/protected_regular in proc(5).
/tmp has the sticky bit set so that anyone can create files there, but users can only delete their own files. Although root can bypass this deletion restriction, it can't bypass the above check in open().
Ok I tried this in a different directory than /tmp, as suggested in comments, and it worked as expected. Using that to hone my search terms I was able pretty quickly to find this U&L answer. Beginning with kernel 4.19 the fs.protected_regular kernel parameter was made available. This parameter:
Disallows open of FIFOs or regular files not owned by the user in world writable sticky directories, unless the owner is the same as that of the directory or the file is opened without the O_CREAT flag. The purpose is to make data spoofing attacks harder.
Apparently it's enabled by default. So because /tmp is world-writable and sticky, I can't touch files that aren't mine – even if I'm root. For the record, if I have to disable this feature:
sysctl fs.protected_regular=0
echo 'fs.protected_regular=0' > /etc/sysctl.d/90-writabletemp.conf
But I'll be better off trying to work around it in the code somehow.
EDIT 01 UPDATE:
ERROR Showing UP Warning: mkdir(): Permission denied in
/var/www/html/projeto01/index.php on line 7 Sucess. Dir Created
EDIT 02
Change to FEDORA and is working.
Thank you guys
before submitting this topic I read and tried all the topics here. No success.
The environment is working great until here. Php 7.4, Apache, Mysql Workbench, Atom... i can code and select from database, everything was great.
The code is working with no error execpt it did not create the directory. :/
If i create the dir manually, return the message that it already exist.
After read a lot of topics and get help from facebook.
I did change on group polices. Not worked.
chmod on the folder, not worked.
On CENTOS the apache user is APACHE instead www:data
ls -l /var/www return:
drwxr-x---. 2 apache apache 6 Nov 16 13:19 cgi-bin
drwxrwxrwx. 3 apache apache 39 Mar 19 13:54 html
ls -l /var/www/html return:
-rw-r--r--. 1 root root 86 Mar 19 00:09 info.php
drwxrwxrwx. 2 apache apache 23 Mar 19 13:58 projeto01
ls -l /var/www/html/projeto1 return:
-rwxrwxrwx. 1 root root 148 Mar 19 15:14 index.php
Thanks for the help!
My code is:
> <?php
$name = "images";
if (!is_dir($name)) {
mkdir($name);
echo "Sucess. Dir Created.";
} else {
echo "Dir already exist. $name";
}
?>
It is a Drupal site, where includes/module.inc runs a loop over files in the registry and attempts require_once(). For a number of files this is failing, even though the file permissions are correct and the file should be readable.
I've added debug code to the loop to output to check file perms and contents:
// Debug code
print "$file perms:" . substr(sprintf('%o', fileperms($file)), -4) . "<br>";
print "$file contents:<br>" . htmlspecialchars(file_get_contents($file)) . "<hr>";
// Original Code
require_once $file;
It outputs the file permissions as well as well as the file contents before attempting the require_once. Different pages are failing on different files, the homepage for instance is outputting:
./sites/default/modules/cck/includes/content.token.inc perms:0755
./sites/default/modules/cck/includes/content.token.inc contents:
[filecontent]
./sites/default/modules/filefield/filefield.token.inc perms:0644
./sites/default/modules/filefield/filefield.token.inc contents:
[filecontent]
./sites/default/modules/getid3/getid3.install perms:0644
./sites/default/modules/getid3/getid3.install contents:
[NO FILE CONTENT]
So for some reason ./sites/default/modules/getid3/getid3.install allegedly has the permission to be readable, but isn’t.
Different paths show different files as being problematic:
/
./sites/default/modules/getid3/getid3.install perms:0644
/admin
./sites/default/modules/webform/components/date.inc perms:0644
/user
./sites/default/modules/cck/includes/content.crud.inc perms:0755
EDIT:
Note above that ./sites/default/modules/cck/includes/content.token.inc is readable but ./sites/default/modules/cck/includes/content.crud.inc gives error, here's the directory listing for those files (including --context to check for SELinux)
# ll --context
total 168
drwxr-xr-x 4 root root ? 4096 Sep 28 05:50 ./
drwxr-xr-x 8 root root ? 4096 Nov 6 2013 ../
-rwxr-xr-x 1 root root ? 72264 Nov 6 2013 content.admin.inc*
-rwxr-xr-x 1 root root ? 26307 Sep 28 03:13 content.crud.inc*
-rwxr-xr-x 1 root root ? 7181 Nov 6 2013 content.devel.inc*
-rwxr-xr-x 1 root root ? 3868 Nov 6 2013 content.diff.inc*
-rwxr-xr-x 1 root root ? 15914 Nov 6 2013 content.node_form.inc*
-rwxr-xr-x 1 root root ? 12550 Nov 6 2013 content.rules.inc*
-rwxr-xr-x 1 root root ? 6246 Nov 6 2013 content.token.inc*
drwxr-xr-x 3 root root ? 4096 Nov 6 2013 panels/
drwxr-xr-x 3 root root ? 4096 Nov 6 2013 views/
The modified date of crud is me commenting the code for testing after the errors occurred, but it is back to as it was now.
EDIT 2:
It seems that trying to access robots.txt directly is also forbidden. Not sure if this is the same problem, but again the file looks like it should be perfectly readable.
# ll robots.txt
-rw-r--r-- 1 6226 6226 1521 Aug 6 18:07 robots.txt
EDIT 3:
Looks like the problem was AppArmor, which I suppose is similar to SELinux. Changing from aa-enforce to aa-complain resolved the issue.
Perhaps some selinux cmd like might get this running :
semanage fcontext -a -t httpd_httpd_sys_content_t '/var/lib/myapp(/.*)?'
restorecon -R -v /var/lib/myapp
Where /var/lib/myapp is your ./ directory
Looks like the problem was AppArmor, which I suppose is similar to SELinux. Changing from aa-enforce to aa-complain resolved the issue.
I'm trying to create a folder in php and the code kind of fails each it is used with /tmp/... as path:
exec("mkdir -p /tmp/test/ 2>&1", $output, $return_code);
// $output is empty, $return_code is 0
//mkdir("/tmp/test/"); // Alternative to above
is_dir("/tmp/test/"); // returns true
is_readable("/tmp/test/"); // returns true
But if i check the /tmp-Folder there is no such directory and all subsequent write or read operations on the folder fail, because the folder does not exist. The permissions for /tmp are correct (root:root with 777) and i can do sudo -u http mkdir -p /tmp/test without problems. If I use tmp/test for example, the code will run fine and create a folder within the directory of the php-skript (Which lies in a folder which belongs to me, not the http-user ... )
Any ideas as to why php fails to create a folder under /tmp/ but reports it as being there?
Edit:
To specify read- and write-actions: Those actions are not from within my own script, but rather external skripts which get called by the php-script to execute different tasks. Once all of them succeeded, the folder gets zipped and copied somewhere else.
Edit:
Right after running exec("mkdir -p /tmp/testfolder");
[daishy#littlezombie tmp]$ pwd
/tmp
[daishy#littlezombie tmp]$ ls -al
insgesamt 8
drwxrwxrwt 21 root root 440 3. Aug 18:56 .
drwxr-xr-x 20 root root 4096 10. Jun 16:49 ..
drwxrwxrwt 2 root root 40 3. Aug 09:42 .font-unix
drwxr-xr-x 2 daishy users 60 3. Aug 14:40 hsperfdata_daishy
drwxrwxrwt 2 root root 60 3. Aug 09:42 .ICE-unix
drwx------ 2 daishy users 60 3. Aug 12:35 kde-daishy
drwx------ 2 daishy users 140 3. Aug 18:49 ksocket-daishy
drwx------ 3 root root 60 3. Aug 18:54 systemd-private-5rIfGj
drwx------ 3 root root 60 3. Aug 09:42 systemd-private-HGNW9x
drwx------ 3 root root 60 3. Aug 09:42 systemd-private-od4pyY
drwx------ 3 root root 60 3. Aug 09:42 systemd-private-qAH8UK
drwxrwxrwt 2 root root 40 3. Aug 09:42 .Test-unix
drwx------ 4 daishy users 80 3. Aug 16:55 .Trash-1000
-r--r--r-- 1 root root 11 3. Aug 09:42 .X0-lock
drwxrwxrwt 2 root root 60 3. Aug 09:42 .X11-unix
drwxrwxrwt 2 root root 40 3. Aug 09:42 .XIM-unix
Edit:
As it turns out, this is not a problem with php, but rather with systemd / apache. In short: systemd creates a private tmp-folder for apache while running, which resides under /tmp/systemd-private-XYZ. So the real /tmp is not viewable by the php-skript, but rather the private one.
See http://blog.oddbit.com/post/private-tmp-directories-in-fedora for more infos.
As it turns out, this is not a problem with php, but rather with systemd / apache. In short: systemd creates a private tmp-folder for apache while running, which resides under /tmp/systemd-private-XYZ. So the real /tmp is not viewable by the php-skript, but rather the private one.
To disable this behavior, you can set PrivateTmp=false in /usr/lib/systemd/system/httpd.service
See http://blog.oddbit.com/2012/11/05/fedora-private-tmp/ for more infos.
Don't do that. Use PHP's awesomely called function, tmpfile(). From the docs:
$temp = tmpfile();
fwrite($temp, "writing to tempfile");
fseek($temp, 0);
echo fread($temp, 1024);
fclose($temp); // this removes the file
When I try to shell_exec('/home/user/scripts/./script') I get the following error:
terminate called after throwing an instance of 'boost::filesystem3::filesystem_error'
what(): boost::filesystem::create_directory: Permission denied: "/.script"
Aborted (core dumped)
shell_exec('whoami') returns www-data on my web-facing php script.
The permissions to the directory and file are exactly the same:
-rwxrwxr-x 1 user123 group456 8246 Jun 25 06:10 script
drwxrwxr-x 7 user123 group456 4096 Jul 10 14:54 .
In fact I can shell_exec('touch /home/user/scripts/test') and it will create the file with no problem.
$ ls -l /home/user/scripts/test
-rw-r--r-- 1 www-data www-data 0 Jul 10 14:54 test123
This is how my groups are set up for each user:
$ groups user123
user123 : group456
$ groups www-data
www-data : group456
Why am I getting this error?
The script your running has a typo: it's trying to make the folder /.script in the root folder instead of ./script (relative path).
Are you trying to execute script at /home/user/scripts/./script then you should run as shell_exec('sh /home/user/scripts/script')
When you add ./ there on path its interpreted differently.
When you pass ./script - You are referring to filename script in current directory.
Also you are actually getting error from your c program which tells us your system is stopping apache to gain root privileges. You can audit2allow to let apache gain needed privileges.