Permission denied despite appropriate permissions

2019-01-12 08:35发布

问题:

I'm trying to read a file in PHP and I'm getting a permission denied error although everybody has read access to the file.

The PHP code:

$config=file_get_contents('/opt/jenkins/home/config.xml');

The error:

Warning: file_get_contents(/opt/jenkins/home/config.xml): failed to open stream: Permission denied in [...]

The filesystem permission:

There is a symlink pointing /opt/jenkins/home/ to /var/lib/jenkins and everybody has read permission on the symlink, actual folder, and file.

$ ls -lh /opt/jenkins/
lrwxrwxrwx 1 sysadmin sysadmin   16 2011-08-04 08:12 home -> /var/lib/jenkins

$ ls -lh /var/lib/ | grep jenkins
drwxr-xr-- 6 jenkins adm     4.0K 2011-08-04 10:04 jenkins

$ ls -lh /var/lib/jenkins/config.xml
-rwxr-xr-- 1 jenkins adm 3.9K 2011-08-04 10:05 /var/lib/jenkins/config.xml

Apache configuration

Configured to folllow symlinks (Options All). Adding a Directory directive for /var/lib/jenkins/ makes no difference.

<Directory /opt/jenkins/home/>
        Options All
        AllowOverride All
        Order Allow,Deny
        Allow from All
</Directory>

Additional info

Whether I use the path through the symlink ("/opt/jenkins/home/config.xml") or the real path ("/var/lib/jenkins/config.xml") I have the same problem.

apache2 version=2.2.14-5ubuntu8.4
php version=5.3.2-1ubuntu4.9

Any idea as to why I'm getting the error?

回答1:

Your directory needs execute permission for this to work. It does not seem to have world execute, and since jenkins is probably not the apache user, and the apache user is not in the adm group, it wouldn't work:

$ ls -lh /var/lib/ | grep jenkins
drwxr-xr-- 6 jenkins adm     4.0K 2011-08-04 10:04 jenkins

Per example:

netcoder@netcoder:~$ mkdir foo
netcoder@netcoder:~$ echo hello > foo/bar
netcoder@netcoder:~$ chmod 777 foo/bar
netcoder@netcoder:~$ ls -lsah foo/bar 
4.0K -rwxrwxrwx 1 netcoder netcoder 6 2011-08-04 08:22 foo/bar
netcoder@netcoder:~$ chmod 444 foo/
netcoder@netcoder:~$ ls -lsah | grep foo
4.0K dr--r--r--  2 netcoder netcoder 4.0K 2011-08-04 08:22 foo
netcoder@netcoder:~$ cat foo/bar 
cat: foo/bar: Permission denied

Even though foo/bar has 0777 permission, if the directory does not have the execute permission, reading its contents is denied.

You'll need the permission to be set for both the target directory and the symbolic link.



回答2:

You need the execute bit set on all directories in the hierarchy up to that file.

chmod o+x /var/lib/jenkins

should do the trick.

(Note: ls -lhd /var/lib/jenkins is a bit better than ls -lh ...|grep jenkins)



回答3:

Lots of modern boxes (digital ocean, rackspace etc) ship with SELinux (Security Enhanced Linux) for RedHat compatible OSs (like CentOS). This throws another wrench into the works which you need to keep in mind. You can have your permissions perfectly set and it will still say permission denied. You need to define a writable context for SELinux:

sudo chcon -t httpd_sys_rw_content_t /data/www/html/sites/mysite -R



回答4:

Most likely your apache user is not allowed to read or access the web files

  1. Check what user is apache running as:

    $ ps aux | grep [a]pache
    root     40283  0.0  0.2 472548 21116 ?        Ss   14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40287  0.0  0.1 472760  8800 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40288  0.0  0.1 472760  8540 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    www-data 40289  0.0  0.1 472776  8540 ?        S    14:38   0:00 /usr/sbin/apache2 -k start
    
  2. Check the path ownership of your web files:

    $ namei -mol /home/john/app2/
    f: /home/john/app2/
    drwxr-xr-x root root  /
    drwxr-xr-x root root  home
    drwx------ john john  john         # <== Ahaa, no access for apache user!
    drwxr-xr-x john john  john app2
    
  3. Adjust permissions accordingly:

Well in this step I will leave it up to you, you can either (a) the make apache user 'john' in this example. Or you could (b) move the web folder to a place outside home. Where the execute access can be given to the group or to even others without breaking security good practices.

a. Make apache user john (ONLY FOR DEV SITES or if you know what you are doing)

sudo vi /etc/apache2/envars 
# replace 
export APACHE_RUN_USER=www-data 
export APACHE_RUN_GROUP=www-data
# with
export APACHE_RUN_USER=john 
export APACHE_RUN_GROUP=john

b. Move that folder out of home... what is it doing there anyways?

sudo mv /home/john/app2 /var/www/

Remember to change the site to match this directory and to restart the apache server.

Here are some references:

https://wiki.apache.org/httpd/13PermissionDenied

http://wiki.apache.org/httpd/FileSystemPermissions