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
Then use a realm which doesn't do that ...
Created attachment 9763 [details] patch to save only when user database is modified
Here is a simple patch that should prevent unnecessary file modifications. Could it be applied or is the "always write file" a feature ?
How does this patch help? If modified, you still have to write the file and therefore still require the same directory/security permissions.
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.
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).
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" ?
Created attachment 9814 [details] replacement for previous buggy patch
-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.
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.
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.
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); }
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.
If you only modify an existing user, the change isn't detected and won't be saved unless you add/remove another user.
Created attachment 9829 [details] complete the first patch to correctly detect all modifications
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.
Created attachment 9948 [details] patch containing fix for pathnameOld
If this solution doesn't fit, I could provide a ReadOnlyMemoryUserDatabase implementation.