Can not write to folder and file with 777 permission

cffile tag cannot write to system file, error: Write access denied to source file [/test/file.out]
In Lucee console, Security – Access menu, file access is set to ‘all’

$ ll “/test/file.out”
-rwxrwxrwx 1 tomcat tomcat 0 Feb 18 21:52 /test/file.out*
$ ls -ld /test
drwxrwxrwx 2 tomcat tomcat 4096 Feb 18 21:52 /test

fileinfo function for file /test/file.out also indicate write false.
Write to system temp /tmp also failed.

tomcat process:

tomcat 118840 1 1 Feb18 ? 00:18:43 /usr/lib/jvm/java-11-openjdk-amd64/bin/java -Djava.util.logging.config.file=/var/lib/tomcat9/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.awt.headless=true -Xms4096m -Xmx4096m -Dlucee.base.dir=/opt/lucee/config/server/ -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/share/tomcat9/bin/bootstrap.jar:/usr/share/tomcat9/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat9 -Dcatalina.home=/usr/share/tomcat9 -Djava.io.tmpdir=/tmp org.apache.catalina.startup.Bootstrap start

OS:
Linux xx 5.11.0-1025-aws #27~20.04.1-Ubuntu SMP Fri Jan 7 13:09:56 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Java Version:
openjdk version “11.0.13” 2021-10-19
OpenJDK Runtime Environment (build 11.0.13+8-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.13+8-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

Tomcat Version:
Server version: Apache Tomcat/9.0.31 (Ubuntu)
Server built: Oct 20 2020 12:27:39 UTC
Server number: 9.0.31.0

Lucee Version: Lucee 5.3.8.206 Gelert

Never use 777, may as well just give me your credit card, any personal incriminating information and I will still be no where as vicious as what awaits you when you’re breached.

without viewing the code that creates the output file
where ever you are sending the temp file, lucee and or the wrapper for lucee (www-data) need at least read, write access

Example
if your code creates a temp file in
/outsidewebroot/
and /outsidewebroot/ is mounted on /LuceeRocksCML/outsidewebroot/
And (This is where it gets fun)
You expect your lucee install which is wrapped as www-data,www-data running behind a proxy
then www-data would need access to /LuceeRocksCML/outsidewebroot

additionally as its Ubuntu you will have to check your ACL access, as Ubuntu has decided to do what they think its better than 50+ years of *NIX knowledge powering over a billion devices

so for acl access to show what something has
getfacl /some/directory

to set an acl for something its
setfacl -args /somefileordirectory

Thank you very much for your reply.
I use the 777 permission for testing, not sure what block lucee from write file

code that create the file:

<cffile action="write" file="/test/file.out" output="123" charset="utf-8">

ACL output:

$ getfacl /test
getfacl: Removing leading '/' from absolute path names
# file: test
# owner: tomcat
# group: tomcat
user::rwx
group::rwx
other::rwx

$ getfacl /test/file.out
getfacl: Removing leading '/' from absolute path names
# file: test/file.out
# owner: tomcat
# group: tomcat
user::rwx
group::rwx
other::rwx

That all is odd. Can you successfully write to Lucees temp location? Try:

<cffile action="write" file="#getTempDirectory()#file.out" output="123" charset="utf-8">

If successfull, dump getTempDirectory(), to see where the file location is, then try looking at the ACL/ownership of those. Compare it with /test/file.out. Also, try removing manually /test/file.out, recreate manually /test/ giving it permissions accordingly and restart Lucee/Tomcat.

1 Like

I agree with @andreas, it could be your temp directory doesnt have permissions to be read / written to by lucee or the tomcat wrapper service.

Lastly, and this is kind of off topic but,…
Have you tried this without the character-set attribute?

Either you are using EXT4 or ZFS, neither care about your encoding. A file for either is a databit, its path and name are just attributes that make up the data storage use of the bit. Both have unquie other mechanisms, but the baseline is the same in terms of how data is stored.

Even if it doesn’t fix your issue, its just a bit of code you can skip for memory sake, where on a Windows box or a cluster of servers who all are mixed oses and read off the same code.

Thanks a lot for your reply, I can write to getTempDirectory() folder.

$ cat /opt/lucee/config/web/156211e6b96f8918f42f2de18f960db41/temp/file.out
123
$ ll /opt/lucee/config/web/156211e6b96f8918f42f2de18f960db41/temp/file.out
-rw-r----- 1 tomcat tomcat 4 Feb 28 00:15 /opt/lucee/config/web/156211e6b96f8918f42f2de18f960db4/temp/file.out

Change the folder and file owner to tomcat prompt error: Invalid file [/test/file.out] Permission denied

$ ls -ld /test/
drw-r----- 2 tomcat tomcat 4096 Feb 28 00:23 /test/

$ ll /test/file.out
-rw-r----- 1 tomcat tomcat 0 Feb 28 00:23 /test/file.out

lucee.runtime.exp.ApplicationException: Invalid file [/test/file.out] at lucee.runtime.tag.FileTag.checkFile(FileTag.java:1205) at lucee.runtime.tag.FileTag.actionWrite(FileTag.java:714) at lucee.runtime.tag.FileTag.doEndTag(FileTag.java:476) at w_cfm$cf.call(/cfm/w.cfm:1) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:1034) at lucee.runtime.PageContextImpl._doInclude(PageContextImpl.java:926) at lucee.runtime.listener.ClassicAppListener._onRequest(ClassicAppListener.java:65) at lucee.runtime.listener.MixedAppListener.onRequest(MixedAppListener.java:45) at lucee.runtime.PageContextImpl.execute(PageContextImpl.java:2460) at lucee.runtime.PageContextImpl._execute(PageContextImpl.java:2450) at lucee.runtime.PageContextImpl.executeCFML(PageContextImpl.java:2421) at lucee.runtime.engine.Request.exe(Request.java:45) at lucee.runtime.engine.CFMLEngineImpl._service(CFMLEngineImpl.java:1179) at lucee.runtime.engine.CFMLEngineImpl.serviceCFML(CFMLEngineImpl.java:1125) at lucee.loader.engine.CFMLEngineWrapper.serviceCFML(CFMLEngineWrapper.java:97) at lucee.loader.servlet.CFMLServlet.service(CFMLServlet.java:51) at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.valves.RemoteIpValve.invoke(RemoteIpValve.java:747) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:367) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.base/java.lang.Thread.run(Thread.java:829)

The problem is we cannot use the temp directory, there are more than one server that receive uploaded image from web page. We need to write to share folder, seems like there is a scope that lucee control write access to.

Thank you Terry. I tried without the character-set, still have the error: Invalid file [/test/file.out] Permission denied

That’s really odd. Did you also try using the full file location including the file system type protocol file://test/file.out ? Also, what happens if you su to the user tomcat and try editing or removing the file manually? Any errors?

Also, I’m not very sure, but wouldn’t the directory /srv/ be more appropriate for that purpose? @Terry_Whitney please correct me if I’m wrong, but I’d do such uploads/writes to “/srv/www_writes/file.out” or similar, or not?

It doesnt matter where you put the file(s) what matters in LINUX is group and file ownership and directory security.

if the file is NFS mounted and you are running lucee under tomcat, then the tomcat user and group needs read / write access to /svr/www_writes

the command would be
chown -R tomcat:tomcat /svr

another way to do this would be with symbolic links
in your web directory you could do
ln -s /svr/www_writes /var/www/html/www_writes

1 Like

The tomcat9 package on Debian/Ubuntu uses systemd and leverages its
sandboxing feature to limit the write access to the conf, log, work and
webapps directories by default. Detail: /usr/share/doc/tomcat9/README.Debian

2 Likes

While sand boxing is the reason, the solution then is:

vi /etc/systemd/system/multi-user.target.wants/tomcat9.service
ProtectSystem=false

After that run:

sudo systemctl daemon-reload
sudo service tomcat9 restart
1 Like