17

What I want do to is to include 'file1.php' from 'domain1' into 'file2.php' on 'domain2'. So what I figured I should do is something like this:

file2.php
require_once '/var/www/vhosts/domain1/httpdocs/file1.php';

But this won't work for reasons I can't truly grasp. So what I did was to add my path to the include path. Something like:

file2.php
set_include_path(get_include_path() . PATH_SEPARATOR . "/var/www/vhosts/domain1/httpdocs");
require_once 'file1.php';

So can you please give me some hints as of where I'm doing wrong ?

Thanks

UPDATE - Either way I get the following error message:

Fatal error: require() [function.require]: Failed opening required '/var/www/vhosts/domain1/httpdocs/file1.php' (include_path='.:/php/includes:/usr/share/pear/') in /var/www/vhosts/domain2/httpdocs/file2.php on line 4

Also I have tried this both with safe_mode On and Off.

UPDATE2: Also I've changed the permissions to 777 on my test file and I've double-checked the paths to the include file in bash.

SOLUTION: I've managed to solve the mystery! My hosting company uses Plesk to manage domains and such. Also the error reporting level in php.ini was not E_ALL. When I set error reporting to E_ALL I got a warning saying:

Warning: require() [function.require]: open_basedir restriction in effect.

So I went in /var/www/vhosts/domain2/conf/httpd.include and edited the open_basedir path. Note that this is not a durable solution since this config file is rewritten by plesk each time the domain config is changed. What you should do is edit (or create) the 'vhost.conf' file in the same directory and then run:

 /usr/local/psa/admin/sbin/websrvmng --reconfigure-vhost --vhost-name=DOMAIN.TLD

This should reconfigure the settings for your domain but for some strange reason it won't work with open_basedir. I can modify other things like document_root but it won't change open_basedir, but that's another problem :D

SOLUTION FINAL: For those with the same problem here is the final code that worked. I just added this in /var/www/vhosts/domain2/conf/vhost.conf (you can change '/var/www/vhosts' to '/' or anything you like):

    <Directory /var/www/vhosts/DOMAIN.TLD/httpdocs>
    <IfModule mod_php5.c>
            php_admin_flag engine on
            php_admin_flag safe_mode off
            php_admin_value open_basedir "/var/www/vhosts"
    </IfModule>
            Options -Includes -ExecCGI
    </Directory>

Thank you all guys!

Brayn
  • 1,766
  • 10
  • 27
  • 33
  • "won't work" doesn't help us identify the problem. What does happen? What errors are reported (including in the server logs)? – Quentin Mar 03 '10 at 09:41
  • 1
    Re your update, this sounds like the file doesn't exist or the rights are not properly set. Are you 1000% sure it exists? Who does it belong to (user/group)? Which user does PHP run as? – Pekka Mar 03 '10 at 09:45
  • How can I check which user PHP uses ? – Brayn Mar 03 '10 at 09:47
  • http://de3.php.net/manual/en/function.posix-getuid.php and http://de3.php.net/manual/en/function.posix-getgid.php – Pekka Mar 03 '10 at 09:54
  • Thanks. It runs as Apache ( I run PHP as an Apache module). Also I've changed ownership and permissions accordantly but still won't work. – Brayn Mar 03 '10 at 10:04
  • What does a `file_exists("/var/www/vhosts/domain1/httpdocs/file1.php")` say? – Pekka Mar 03 '10 at 10:06
  • Oddly enough it return false ( I should've thought myself to check this). But when I use the same path in my shell it finds the file. What does this mean ? – Brayn Mar 03 '10 at 10:15
  • That is really odd. Maybe it's a security patch like Suhosin? Can you check whether it's activated by looking into `phpinfo()`? – Pekka Mar 03 '10 at 10:16
  • What happens if you do a `glob()` on `/var/www/vhosts/domain1/httpdocs/`? Do you get anything at all? – Pekka Mar 03 '10 at 10:17
  • I have checked and there is no Suhosin in phpinfo and glob('/var/www/vhosts/domain1/httpdocs') returns nothing. Also I have tried several locations outside the document root of domain2 and I get the same result. It only works it the included file is inside the domain2 webroot. – Brayn Mar 03 '10 at 10:32
  • 1
    Thanks for posting the solution. So many times people figure it out and then just leave it sitting with no resolution. The evil open_basedir does it again. I should have known that was the case, we deal with that all the time at Yahoo. I just thought Yahoo was more paranoid than others. I didn't realize open_basedir was being used much in the wild. Hmmm. I learn something new every day! haha. – Chuck Burgess Mar 09 '10 at 15:06

8 Answers8

9

You can not accomplish this if open_basedir is in effect, which prevents PHP from traversing out of the home directory.

What you can do is make sure that docroot1 and docroot2 are owned by users in the same group, set group permissions accordingly and use a symbolic link from docroot2 to docroot1 to read the other web root.

Or, re-build PHP and let it just follow typical *nix permissions like every other process :)

Tim Post
  • 33,371
  • 15
  • 110
  • 174
2

You can include files from anywhere you want, unless your PHP script's permissions, or the safe mode prevent it. Your first approach is perfectly fine. What errors do you get?

Re the comments, that seem to confirm that there is no access from within PHP to a file that definitely exists. As to what it could be, Suhosin having been ruled out, the only thing I can think of is PHP or Apache being some kind of a a chroot Jail:

The main benefit of a chroot jail is that the jail will limit the portion of the file system the daemon can see to the root directory of the jail. Additionally, since the jail only needs to support Apache, the programs available in the jail can be extremely limited. Most importantly, there is no need for setuid-root programs, which can be used to gain root access and break out of the jail.

I have never worked with anything like this so I can't tell you how to spot it (apart from doing a glob() on /var/www/vhosts and see what comes up. But I think this would have to have been set up by an administrator. Who runs your machine?

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
  • We do (mostly I do) but the hosting company does have some odd security measures ( for example I cannot install PHP extensions directly from PEAR). Thanks for the tip I'll check with them on the jail thing. – Brayn Mar 09 '10 at 07:32
2

This works on a couple of machines i manage

ini_set("include_path",".:/hsphere/local/home/user_name/other_domain.com");
require "filename.php";
Kristoffer Sall-Storgaard
  • 10,576
  • 5
  • 36
  • 46
  • That should have worked also and I have tried it, I've mentioned somewhere around here that I've added the path to the include path. The problem was with the open_basedir setting in php.ini, see the post for the update with what was wrong. Thanks! – Brayn Mar 15 '10 at 08:03
1

I sit here wondering why You didn't jus do a symlink. Or did I mis something? You could symlink a folder with needed includes to the path You have access to.

naugtur
  • 16,827
  • 5
  • 70
  • 113
  • If the current user can't even *see* files outside the current domain's directory, it's likely that there is a security mechanism in place that can't be circumvented with a simple symlink. But it's still worth a try. – Pekka Mar 13 '10 at 16:11
  • he mentioned checking all the files in bash so i expect he has access. – naugtur Mar 13 '10 at 16:32
  • I've tried a symlink but it didn't work ( I've mention that somewhere in the comments. Also I've solved the problem and update the post a while ago. Thanks anyway! – Brayn Mar 15 '10 at 08:02
1

If the error relates to permission (and not file_not_found), whether the location is within documentRoot or Outside it, then the issue is usually selinux. Do not chmod 777 as it is risky without any real benefit; but instead just tell selinux that you are aware of this access by issuing this:

chcon -R -t httpd_sys_rw_content_t /full-path-to-target-folder/

Or let Apache own this as well by issuing the two:

chown -R apache /full-path-to-target-folder/
chcon -R -t httpd_sys_rw_content_t /full-path-to-target-folder/

Also, symbolic links as advised by others, here and other related answers elsewhere, is only necessary if you want to access the file as client. For internal code access, the links are not necessary security-wise.

Ajowi
  • 449
  • 3
  • 12
0

what you are using is bad practice. put the dependent code into domain specific. Duplicating the same code is the right approach as it does not affect the operation of both sites.

Try creating the symlink of file1.php and included that as if it is from the local directory.

also make sure that .htaccess has the followsymlink option set to true

how about trying this in your file2.php in domain2?

require_once '../../../domain1/httpdocs/file1.php';

coder
  • 1,069
  • 3
  • 9
  • 18
  • I don't agree. It's perfectly ok to use some central code library. People do it all the time with PEAR. However it ís bad practice that he puts multiple domain code in one domain. He should just make a folder outside vhosts for it. – douwe Mar 08 '10 at 10:23
  • PEAR is a library which will be part of the include path by default. They are included by the hosting provider. the best approach is always have your dependency locally instead of globally across domains. central code library is useful only within the domain. – coder Mar 08 '10 at 10:29
  • @coder This is what I want to do. In fact there is one domain and one location outside vhosts but that is how I initially posted the question and for the sake of clarity I haven't modified the paths. Thanks. – Brayn Mar 08 '10 at 11:27
  • did you try creating the symlink and use it? – coder Mar 08 '10 at 11:43
  • @coder I haven't tried that yet but it just might work. I'll get to it now. – Brayn Mar 08 '10 at 12:15
  • @coder I have tried creating a symlink pointing to my include file but it still gives me the "Failed opening required" error. Also I have modified my .htaccess adding "Options +FollowSymlinks" and the restarted the apache daemon. I have chowned both the symlink and the file to the apache user and chmodded them to 777 just to be sure. I really don't know what's wrong with my includes :( – Brayn Mar 08 '10 at 13:51
  • I think "../../../[...]" is one too many. But I have tried with both "../../../[...]" and "../../[...]" and I still get the same error. If I do "../../[...]" in bash it works just fine... – Brayn Mar 08 '10 at 17:41
0

Try chmod 777 on a test php file to see if that works, if it does you have permission issues. Also do a simple phpinfo() and see if save mode is on.

douwe
  • 1,305
  • 10
  • 12
  • I have tried that. See the direct comments for the question for other tests I did. Thanks. – Brayn Mar 08 '10 at 11:25
0

What happens if you try to require a different file:

// test.php
<?php
   echo 'Hello World';
?>

// your file
require_once('test.php');

Does that work? If so, put test.php in the other location and try it again. Does it still work?

Chuck Burgess
  • 11,600
  • 5
  • 41
  • 74
  • I have tried with several files. If the included file is on the same domain ( in the same webroot) it works fine. If I move the file to any other location outside that it won't work. – Brayn Mar 09 '10 at 07:31