Bug 25822 - tomcat shouldn't write tomcat-users.xml at startup
Summary: tomcat shouldn't write tomcat-users.xml at startup
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 5.0.16
Hardware: PC Linux
: P3 enhancement (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2003-12-30 12:38 UTC by Xavier Poinsard
Modified: 2004-11-16 19:05 UTC (History)
0 users



Attachments
patch to save only when user database is modified (8.18 KB, patch)
2003-12-31 13:45 UTC, Xavier Poinsard
Details | Diff
replacement for previous buggy patch (3.60 KB, patch)
2004-01-05 15:56 UTC, Xavier Poinsard
Details | Diff
complete the first patch to correctly detect all modifications (4.44 KB, patch)
2004-01-06 15:41 UTC, Xavier Poinsard
Details | Diff
patch containing fix for pathnameOld (4.77 KB, patch)
2004-01-14 16:44 UTC, Xavier Poinsard
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Xavier Poinsard 2003-12-30 12:38:14 UTC
I am trying to start tomcat as normal user and carefully adding only required
permissions and I found that during startup tomcat is writing the file
tomcat-users.xml. I think it should only write this file when users are
added/modified/deleted and I think it would be a bad thing to have to make the
entire conf directory writeable since it writes a tomcat-users.xml.new and then
renames it.
I am using the standard binaries.
For info :
30 déc. 2003 13:27:34 org.apache.naming.NamingContext lookup
ATTENTION: Une erreur s est produite durant la résolution de la référence
java.io.FileNotFoundException:
/usr/local/jakarta-tomcat-5.0.16/conf/tomcat-users.xml.new (Permission denied)
        at java.io.FileOutputStream.open(Native Method)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:179)
        at java.io.FileOutputStream.<init>(FileOutputStream.java:131)
        at
org.apache.catalina.users.MemoryUserDatabase.save(MemoryUserDatabase.java:508)
        at
org.apache.catalina.users.MemoryUserDatabaseFactory.getObjectInstance(MemoryUserDatabaseFactory.java:144)
        at
org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:176)
        at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:301)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:837)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:197)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:202)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:172)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:144)
        at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:166)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:2336)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:297)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:398)
30 déc. 2003 13:27:34
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener createMBeans
GRAVE: Exception processing Global JNDI Resources
javax.naming.NamingException:
/usr/local/jakarta-tomcat-5.0.16/conf/tomcat-users.xml.new (Permission denied)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:849)
        at org.apache.naming.NamingContext.lookup(NamingContext.java:197)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:202)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.createMBeans(GlobalResourcesLifecycleListener.java:172)
        at
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener.lifecycleEvent(GlobalResourcesLifecycleListener.java:144)
        at
org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:166)
        at org.apache.catalina.core.StandardServer.start(StandardServer.java:2336)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:581)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:324)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:297)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:398)
30 déc. 2003 13:27:34 org.apache.catalina.core.StandardService start
Comment 1 Remy Maucherat 2003-12-30 15:52:54 UTC
Then use a realm which doesn't do that ...
Comment 2 Xavier Poinsard 2003-12-31 13:45:48 UTC
Created attachment 9763 [details]
patch to save only when user database is modified
Comment 3 Xavier Poinsard 2003-12-31 13:51:34 UTC
Here is a simple patch that should prevent unnecessary file modifications.
Could it be applied or is the "always write file" a feature ?
Comment 4 Yoav Shapira 2003-12-31 13:54:28 UTC
How does this patch help?  If modified, you still have to write the file and 
therefore still require the same directory/security permissions.
Comment 5 Xavier Poinsard 2003-12-31 14:07:17 UTC
If you don't plan to add users using the web interface, with this patch you can
disallow any write in the conf directory and add users only "by hand".
We could perhaps go further by writing the tempory files tomcat-users.xml.old
and tomcat-users.xml.new in the temporary directory. Then only write right on
the file tomcat-users.xml would be required.
But since I am completely ingorant of tomcat internals, I don't where we can get
the tomcat temporary directory.
Comment 6 Yoav Shapira 2003-12-31 14:09:29 UTC
You could use java.io.tmpdir.  I wish you had discussed this on the mailing 
list before posting a bug (which I've now modified to an enhancement request).
Comment 7 Xavier Poinsard 2003-12-31 14:42:23 UTC
Sorry, but I really thought it was a bug since the default configuration was
implying a lower security.
Is java.io.tmpdir better than something like System.getProperty("catalina.base")
+ File.separator+ "temp" ?
Comment 8 Xavier Poinsard 2004-01-05 15:56:57 UTC
Created attachment 9814 [details]
replacement for previous buggy patch
Comment 9 Remy Maucherat 2004-01-05 15:59:59 UTC
-1 for your revised patch, sorry. Please do not reopen the bug.
If you do not agree, write your own custom realm, or use the older memory realm.
Comment 10 Xavier Poinsard 2004-01-05 16:02:24 UTC
My previous patch wasn't able to detect any user modification.
Since it seems to have been applied to cvs, here is a patch that remove it and
uses another method.
Like discussed before, it uses a temporary file to save the file before
overwriting the file in conf directory.
With this patch, write permission is only necessary for the file
tomcat-users.xml and not for the entire directory.
Comment 11 Remy Maucherat 2004-01-05 16:08:06 UTC
Sorry, but I'm not interested. Either something simple works (like your first
patch), or it doesn't. If it doesn't then since the "issue" is not significant,
then the patch will be reverted.
Comment 12 Xavier Poinsard 2004-01-05 16:19:24 UTC
My first patch doesn't work since it doesn't detect user modification.
My second remove the first patch and implements the following :
- use a temporary file for write instead of conf/tomcat-users.xml.new
- check wether conf/tomcat-users.xml is writable (if it exists)
- rename the temporary files to conf/tomcat-users.xml
It removes the need to write in the directory.

By the way the old code had a very little bug :

        File fileOld = new File(pathnameNew);
        if (!fileOld.isAbsolute()) {
            fileOld =
                new File(System.getProperty("catalina.base"), pathnameOld);
        }

when I expected 

        File fileOld = new File(pathnameOld);
        if (!fileOld.isAbsolute()) {
            fileOld =
                new File(System.getProperty("catalina.base"), pathnameOld);
        }


Comment 13 Remy Maucherat 2004-01-05 16:21:33 UTC
Your first patch works fine (at least it does what I wanted): the users are no
longer saved on startup, while updates using the admin webapp cause the file to
be saved.
Comment 14 Xavier Poinsard 2004-01-05 16:28:04 UTC
If you only modify an existing user, the change isn't detected and won't be
saved unless you add/remove another user.
Comment 15 Xavier Poinsard 2004-01-06 15:41:40 UTC
Created attachment 9829 [details]
complete the first patch to correctly detect all modifications
Comment 16 Xavier Poinsard 2004-01-06 15:43:51 UTC
Since you liked my first patch tentative, I completed it by detecting every
modifications made to the UserDatabase.
I hope this could be accepted since it remains simple.
Comment 17 Xavier Poinsard 2004-01-14 16:44:20 UTC
Created attachment 9948 [details]
patch containing fix for pathnameOld
Comment 18 Xavier Poinsard 2004-01-14 16:46:42 UTC
If this solution doesn't fit, I could provide a ReadOnlyMemoryUserDatabase
implementation.