3

I am trying to create a custom mlocate db for my home directory. When running the updatedb it complains about inability to open a temporary file.

55;~/>uname -a
Linux yoga 4.12.14-lp151.28.59-default #1 SMP Wed Aug 5 10:58:34 UTC 2020 (337e42e) x86_64 x86_64 x86_64 GNU/Linux
56;~/>updatedb --version
updatedb (mlocate) 0.26
...
57;~/>updatedb -l 0 -o ~/.home-mlocate.db -U ~/
updatedb: can not open a temporary file for `/home/<user>/.home-mlocate.db'

Prepending updatedb with sudo or running as root does not change the outcome. Running simply sudo updatedb without any arguments succeeds.

More generally unless the database is the default one updatedb can not create temporary file:

yoga:~ # /usr/bin/whoami
root
yoga:~ # /usr/bin/updatedb ; echo $?
0
yoga:~ # /usr/bin/updatedb -o /var/lib/mlocate/mlocate.db ; echo $?
0
yoga:~ # /usr/bin/updatedb -o /var/lib/mlocate/custom-mlocate.db ; echo $?
/usr/bin/updatedb: can not open a temporary file for `/var/lib/mlocate/custom-mlocate.db'
1
yoga:~ # /usr/bin/strace /usr/bin/updatedb -o /var/lib/mlocate/custom-mlocate.db 2>&1 1>\dev\null | grep "openat.*custom-mlocate.db"
openat(AT_FDCWD, "/var/lib/mlocate/custom-mlocate.db", O_RDWR) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/var/lib/mlocate/custom-mlocate.db.6JiH9O", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)
yoga:~ #  

My operating system is openSUSE Leap 15.1 and my /home directory is on an ext4 file system.

What is the problem and how it is to be resolved?

fra-san
  • 9,931
  • 2
  • 21
  • 42
R. Matveev
  • 71
  • 7
  • You write "prepending `updatedb` with `sudo` ... does not change the outcome. Running simply `sudo updatedb` succeeds". Where's the difference? Can you clarify? – eblock Aug 31 '20 at 10:10
  • @eblock What I meant is that running `updatedb` as a root and without any arguments runs successfully and updates the default database. I have edited the question to clarify. – R. Matveev Aug 31 '20 at 11:12
  • You might try running the command with `strace` to see if it throws any light on *why* the temporary file creation fails – steeldriver Aug 31 '20 at 12:07
  • The error message indicates that you do not have write permission in the directory where you're writing the output database. Did you write the command exactly as shown in the question, and if so, are you able to create other files under `~/`? – Kusalananda Aug 31 '20 at 12:17
  • @Kusalananda It seems so, but why? It is my home dir and I can access files in it any way I like. There seem to be no problem outside of `updatedb`. Also running as root has the same access problem. – R. Matveev Aug 31 '20 at 12:43
  • Run the command with `strace` as steeldriver suggested and see what you can find out about the call to `mkstemp()` from the output. – Kusalananda Aug 31 '20 at 12:49
  • @steeldriver `strace updatedb -o ~/.home-mlocate.db -U ~/` gives `...openat(AT_FDCWD, "/home//.home-mlocate.db.ZvgxzG", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied)...`. And `sudo strace updatedb -o ~/.home-mlocate.db -U ~/` gives the same. I can write to `~/` no problem. – R. Matveev Aug 31 '20 at 12:50
  • @Kusalananda There is no call to `mkstemp()` in the output from `strace`. I think the offending line is as in my previous comment. – R. Matveev Aug 31 '20 at 12:55
  • @R.Matveev Well, the `mkstemp()` call generates a call to `openat()` later, and that's what you see in the output from `strace` so that's ok. – Kusalananda Aug 31 '20 at 13:10
  • @Kusalananda How do I analyse the problem further? The corresponding call `openat()` for the tmp file succeeds when running `updatedb` without arguments. – R. Matveev Aug 31 '20 at 13:14
  • @Kusalananda I have created an entirely new user. Logged in as the new user in the corresponding home dir the problem persists. – R. Matveev Aug 31 '20 at 13:28
  • What type of Linux is this, exactly? what filesystem do your users' home directories reside on (ex. output of `findmnt -T ~/` or equivalent) – steeldriver Aug 31 '20 at 14:10
  • @steeldriver opensuse Leap 15.1. is the distro. `/home` is on ext4. After some experimentation: `updatedb` is not able to create tmp file once `-o` option is given, regardless of the location of the file and permissions of the process. E.g. running as root and in the dir `/var/lib/mlocate`, where the default database sits. – R. Matveev Aug 31 '20 at 14:17
  • Is SELinux installed on your system? Have you checked your logs for security-related messages? – fra-san Aug 31 '20 at 16:07
  • Yes, selinux is installed. Which logs shall I look into? – R. Matveev Aug 31 '20 at 16:36
  • According to the [openSUSE documentation](https://doc.opensuse.org/documentation/leap/security/html/book.security/cha-selinux.html#sec-selinux-troubleshoot), it should be `/var/log/audit/audit.log`. – fra-san Aug 31 '20 at 16:59
  • @fra-san I solved it. Thanks so much. I would never figure it out by myself and would just go crazy. – R. Matveev Sep 01 '20 at 07:14
  • Thank you everybody who spent time on this – R. Matveev Sep 01 '20 at 07:36

2 Answers2

2

As was suggested by @fra-san the problem was caused by security policies. The solution is

  1. Make sure you have audit daemon running and audit2allow installed. For opensuse audit daemon is in the package audit, and audit2allow is in policycoreutils. Install if not present and start the daemon as root
systemctl start auditd
  1. Run the offending program, e.g. updatedb -o ~/custom-mlocate.db -U ~/ as a normal user. The rest should be executed logged in as root (bad) or prepending each line with sudo (good).

  2. Examine the last few lines of /var/log/audit/audit.log

    tail -n 20 /var/log/audit/audit.log | grep -i denied
    

    You are interested in the line that starts with type=AVC and where the name of the offending command appears. There are two possibilities:

  • The line contains avc: denied. Your system uses SELinux.
  • The line contains apparmor="DENIED". It means your system uses AppArmor for security.

If it is AppArmor, consult AppArmor manuals. E.g. https://doc.opensuse.org/documentation/leap/security/html/book.security/part-apparmor.html for OpenSuse.

For SELinux:

  1. Copy the line you identified in step 3 to a separate file. E.g.
    tail -n 20 /var/log/audit/audit.log | grep -i "denied.*updatedb" > /var/log/audit/audit-partial-tmp.log
    
    Check that it is OK
    cat /var/log/audit/audit-partial-tmp.log
    
    and
    audit2allow -w -i /var/log/audit/audit-partial-tmp.log
    
  2. Create SELinux module
    audit2allow -i /var/log/audit/audit-partial-tmp.log -M custom-selinux-module
    
  3. Make new policy active
    semodule -i custom-selinux-module.pp
    
  4. Run the program as a normal user to check whether it is ok. E.g.
    updatedb -o ~/custom-mlocate.db -U ~/
    
  5. Cleanup
    rm /var/log/audit/audit-partial-tmp.log custom-selinux-module.pp 
    
R. Matveev
  • 71
  • 7
0

If you have write permission to the database file, but not to the directory in which it was created, then you can workaround this issue by writing the database somewhere else where you do have directory-write permission and then copying it to the final file location e.g.

updatedb -o /myhomedir/mydb.db
cp /myhomedir/mydb.db /somespeciallocation/mydb.db