1

I'm trying to access an SQLite file on a CentOS7 box using PHP and the PDO library. I was getting read-only errors just like this question - https://stackoverflow.com/questions/3319112/sqlite-read-only-database

And per that question, the answer was to disable SELinux. That's fine for development, but for a production system I'd like to keep SELinux enabled.

How do I leave SELinux enabled, without getting read-only errors on the SQLite file?

(Note: The answers in that question that relate to it don't seem to be CentOS 7 compatible).

Edit: tail -f /var/log/audit/audit.log

type=AVC msg=audit(1543600144.088:1845): avc: denied { write } for pid=13968 comm="httpd" name="html" dev="dm-0" ino=50632493 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:httpd_sys_content_t:s0 tclass=dir type=SYSCALL msg=audit(1543600144.088:1845): arch=c000003e syscall=2 success=no exit=-13 a0=5567d0b40859 a1=80042 a2=1ff a3=5567d0b40859 items=0 ppid=13674 pid=13968 auid=4294967295 uid=48 gid=48 euid=48 suid=48 fsuid=48 egid=48 sgid=48 fsgid=48 tty=(none) ses=4294967295 comm="httpd" exe="/usr/sbin/httpd" subj=system_u:system_r:httpd_t:s0 key=(null) type=PROCTITLE msg=audit(1543600144.088:1845): proctitle=2F7573722F7362696E2F6874747064002D44464F524547524F554E44

Pipupnipup
  • 11
  • 3

2 Answers2

3

By default PHP (which runs under the httpd_t domain) is not allowed to write files in most locations on the system, other than temporary directories.

You can set a specific file to be writable by changing its context to httpd_sys_rw_content_t. For example, to change the context temporarily:

chcon -t httpd_sys_rw_content_t /var/lib/myapp/database.sqlite

To make this permanent, you need to set a permanent file context matching the file, so that it will always be labeled this way. You do this with semanage fcontext.

semanage fcontext -a -t httpd_sys_rw_content_t /var/lib/myapp/database.sqlite
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • Thanks Michael. I'm afraid neither of those commands works for me. I've changed the location to be correct, but the second I `setenforce 1`, PHP immediately starts complaining about being unable to open the file. `setenforce 0` then fixes it again. – Pipupnipup Nov 30 '18 at 17:22
  • 1
    OK, what's in the audit log then? – Michael Hampton Nov 30 '18 at 17:34
  • Ok, so apparently there's an audit log.... :-). Tailing it during the request gets me this lot (see question; too long for here) – Pipupnipup Nov 30 '18 at 17:49
  • The alert is on a directory, so you actually need to do what @MichaelHampton said but also on the directory as well. – Matthew Ife Nov 30 '18 at 18:41
  • @Pipupnipup If you need to make a whole directory writable, see [here](https://serverfault.com/a/677805/126632). – Michael Hampton Nov 30 '18 at 19:20
  • Thanks both, but that doesn't work either. This command `semanage fcontext -a -t httpd_sys_rw_content_t /var/www/html(/.*)?; restorecon -RF /var/www/html/` gives me back: `-bash: syntax error near unexpected token `('` - I see that someone else got that same error on that thread too (comment from Derek Miller at the bottom) – Pipupnipup Nov 30 '18 at 20:50
  • You forgot the quotes to escape it from the shell. – Michael Hampton Nov 30 '18 at 20:59
  • @MichaelHampton - Thanks. The linked answer doesn't have quotes and I'm not au-fait enough with linux to know enough to "forget" such things. But I cobbled a solution together per my answer below. – Pipupnipup Nov 30 '18 at 21:01
  • Oops, i didn't notice that at first! – Michael Hampton Nov 30 '18 at 21:02
0

So, from a combination of trial and error, and help from Michael's answer + comments and these:

https://stackoverflow.com/a/41132426

https://stackoverflow.com/questions/3319112/sqlite-read-only-database

The solution is these two lines (assuming the file is in /var/www/html

semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html(/.*)?" restorecon -v /var/www/html

There are caveats:

  • The first line MUST have the path in quote marks or you'll get bash: syntax error near unexpected token ('

  • You must also do it to the entire directory, not just the file. Which is what the weird bit in brackets does.

(Unfortunately I lack the rep to make helpful comments about this in the above linked questions. Or even to vote up/down the right/wrong answers.)

Pipupnipup
  • 11
  • 3