Following symbolic links in Tomcat

We have several web applications derived from the same code base and as well as sharing the jars in WEB-INF/lib, we provide set of administration pages to allow users to configure and administer the applications. Until now, we’ve always had to make copies of the admin pages and this has caused us configuration headaches as we try and make sure that all the applications have the latest versions of all the pages.

But now I’ve finally managed to work out how to make Tomcat follow symbolic links—and it’s very easy! All you have to do is add allowLinking="true" to the Context tag in the context.xml file. For Tomcat 5.5 and later, I find the most convenient way is to have a META-INF directory in the web application directory and have a context.xml file in this. Like this all the files to do with the web application are in the same place and copying and deploying is easy. So, my context.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>

<Context path="/myapp" allowLinking="true">

</Context>

As soon as you restart Tomcat, the change comes into effect and you can share directories between applications or even link to directories outside the web application home directory. If you still using Tomcat 4.x then you can’t use the context.xml in the META-INF directory. Instead you have to put it in the server.xml itself.

Tags: ,

5 Responses to “Following symbolic links in Tomcat”

  1. DenisH Says:

    It turns out that there are a few caveats to using “allowLinking”. First the documentation for the context element for Tomcat 5.5 says: NOTE: This flag MUST NOT be set to true on the Windows platform (or any other OS which does not have a case sensitive filesystem), as it will disable case sensitivity checks, allowing JSP source code disclosure, among other security problems.

    And second, in the migration documentation from 5.5 to Tomcat 6, it says “When using a shared webhosting environment, it is recommended that usage of context.xml inside a WAR is forbidden (using the deployXML attribute of the Host element)”. Presumably this is because it would allow badly behaved configurations to be loaded?

    So, just be aware of these pieces of advice if you are going to use the context.xml and allowLinking.

  2. Neale Rudd Says:

    Hi,

    Just wanted to thank you both for the info on the allowLinking setting.

    We run Australia’s largest/oldest java hosting company and have a customer on a dedicated server who write and operate
    a CMS.

    Usually all their sites run under a single account, but they wanted a way to have a separate account (separate Host entry)
    which uses the WEB-INF, META-INF and data folder from their main CMS account.

    The purpose was so that their client could log in using FTP and create additional folders of static content.
    eg: http://www.example-domain.com/promo

    We found at first that we could symlink META-INF with no problems, but symlinking WEB-INF ended up deploying an
    application with no name (which did not correctly start up). The other alternative was to copy the WEB-INF folder
    into the new webapps_someclient/ROOT folder, but this meant that any code updates needed to be deployed to
    every Host set up in this way.

    After adding the allowLinking flag however, it all works fine.

    As an added benefit, the FTP service has not been set to follow symlinks, so their client can now log in, see the
    META-INF, WEB-INF and data folder links, but cannot change-directory to them, and therefore cannot download
    or edit the application classes.

    Also – good advice by DenisH. This setup is on Linux so does not affect the security.

    We recommend the use of context.xml as it’s the most effective way of allowing customers to upload their applications,
    either unpacked or in a WAR. Other alternatives are placing context files in the conf folder, which limits what customers
    can do, or in server.xml (yuck).

    One recommendation I have however, is to remove path=”/myapp” from your Context tag. It is unnecessary and may
    cause headaches if you relocate the application. If you leave it out, the path defaults to whatever the application
    path is relative to the webapps folder.

    eg:
    /webapps/ROOT – the META-INF/context.xml for this app will default to “/”
    /webapps/myApp – the META-INF/context.xml for this app will default to “/myApp”

    … so leave the path attribute out, then you can copy myApp to myOtherApp and the application will still work properly
    without any modifications to it’s context.xml file.

    The context.xml file is also a great place for JNDI DBCP datasource settings, and Tomcat Realms security file/database location
    settings.

    Regards,
    Neale

  3. enrique marmolejo Says:

    thanks a lot, you save my day an a headache.

  4. Ningappa Says:

    Hi All,

    Using “allowLinking=true” in context.xml of tomcat 6, I am able to access soft links, within the application project directory.
    but the problem is when I undeploy the application by deleting only project.war file, tomcat is deleting all the contents inside the soft links along with that project directory, but for me it’s causing the serious problem by deleting the valuable web content.

    Let me know if you have any clue on this.

    Thanks
    Ningappa

  5. Oli Says:

    Hi,

    following on from this,

    have a simple virtual host with a context element inside, simple one line

    symlinks work fine on one level, so my app directory is x, everything is served from x including symlinks to physical directories or files.

    however if a symlink under x points to another symlink which then points to a physical directory, i get a resource not found error.

    this is the same behaviour for all tomcats 5.5 + works fine in tomcat 5.019/28
    any ideas would be much appreciated

    oli

Leave a Reply