mlocate daily cron job not running

Hi,

I recently noticed that running “locate <something>” in the console does not give me the results it previously did although the file is there.

If I run manually updatedb and try again locate - things are fine.

It seems the reason for the issue is that mlocate does not run its daily job although the script /etc/cron.daily/mlocate.cron is there. Running ‘crontab -l’ as root shows nothing.

What could be the reason for that cron job not running properly and how could I possibly fix it? I remember previously (say a month or two ago) things worked as expected.

I do not know much about mlocate, but one thing is sure, root’s personal crontab (which is what you get when you run.

crontab -l

as root) hasn’t much to do with the running of the daily/weekly/monthly jobs. Those are started from the system crontab which is located in /etc/crontab

Do you see anything wrong:


# cat /etc/crontab 
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root
#
# check scripts in cron.hourly, cron.daily, cron.weekly, and cron.monthly
#
-*/15 * * * *   root  test -x /usr/lib/cron/run-crons && /usr/lib/cron/run-crons >/dev/null 2>&1

Not realy, but of course it tests if /usr/lib/cron/run-crons exists and is executable for the process owner before it runs it. You could do likewise.

Not that I assume that there is realy something wrong with that chain (of course you can check notwithstanding), I only saw what I thought was a misconception in your place, checking root’s crontab where the system crontab is the place where it should start from.

The file is there and is executable:

-rwxr-xr-x 1 root root 7735 Oct 25 12:35 /usr/lib/cron/run-crons*

And how exactly did you “run manually updatedb”?

Normally the cronjob runs updatedb as an unprivileged user (nobody).
If you ran updatedb as root, the cronjob probably cannot write the database any more.

So, what does this say?

ls -la /var/lib/mlocate

Also check that cron is actually active:

systemctl status cron

Login as root and run ‘updatedb’.

Normally the cronjob runs updatedb as an unprivileged user (nobody).
If you ran updatedb as root, the cronjob probably cannot write the database any more.

Then why after doing this the locate command works (i.e. reads from DB)?

Here is also the info:

# ls -la /var/lib/mlocate
total 20900
drwxr-xr-x  2 nobody root     4096 Mar  5 10:01 .
drwxr-xr-x 65 root   root     4096 Mar  4 16:45 ..
-rw-r--r--  1 root   root 21389535 Mar  5 10:01 mlocate.db

# systemctl status cron
cron.service - Command Scheduler
   Loaded: loaded (/usr/lib/systemd/system/cron.service; enabled)
   Active: active (running) since Sat 2016-03-05 13:16:32 EET; 23min ago
 Main PID: 2745 (cron)
   CGroup: /system.slice/cron.service
           └─2745 /usr/sbin/cron -n


Mar 05 13:16:32 i7 cron[2745]: (CRON) INFO (RANDOM_DELAY will be scaled with factor 39% if used.)
Mar 05 13:16:32 i7 cron[2745]: (CRON) INFO (running with inotify support)
Mar 05 13:30:01 i7 cron[3835]: pam_unix(crond:session): session opened for user root by (uid=0)

Reading from the database is not the same as writing to the database.

Here is also the info:

# ls -la /var/lib/mlocate
total 20900
drwxr-xr-x  2 nobody root     4096 Mar  5 10:01 .
drwxr-xr-x 65 root   root     4096 Mar  4 16:45 ..
-rw-r--r--  1 root   root 21389535 Mar  5 10:01 mlocate.db

As you can see, it is owned by root, and only root can write to it (but everybody can read it).

systemctl status cron

cron.service - Command Scheduler
Loaded: loaded (/usr/lib/systemd/system/cron.service; enabled)
Active: active (running) since Sat 2016-03-05 13:16:32 EET; 23min ago
Main PID: 2745 (cron)
CGroup: /system.slice/cron.service
└─2745 /usr/sbin/cron -n


That looks ok.

So I would suggest to try one of the following:


  - set "RUN_UPDATEDB_AS=root" in /etc/sysconfig/mlocate
But this is considered a security risk, note the comment in the file. 
  - delete /var/lib/mlocate/mlocate.db and wait until the system creates it again 
  - probably the best:
 

sudo chown nobody: /var/lib/mlocate/mlocate.db

Thanks wolfi. I have changed ownership to nobody as this is obviously the issue as you explained.

BTW does running this process as nobody ensure that all files will be indexed properly? I have a few ntfs mounts which are with 700 permissions owned by a particular user. What is the proper way to handle that without compromising security?

NTFS is different the ownership is synthetic not actually part of the Windows File system. So ownership is set to whatever at mount time. If said ownership allows nobody user to read then it should be indexed.

Yes, I was talking about the mount ownership. So I will change the group to nobody and give it read permission then. Thanks.

Ah… my bad.

The actual mount points already have ownership user:bacula and 770 permission.

Should I run updatedb as user bacula? Or how should it be done with ACL to add user nobody to be able to read?

What about the files?

In any case you must allow others read access to allow nobody ie the last number should not be 0 to allow others some form of access

if you run as you then you just come back top the problem of the data files not having the correct ownership

Not sure I made myself clear. I have 2 ntfs mount points which have owner user:bacula and permissions 770.

So the question is how to modify the mount in order to allow only user, bacula and nobody to have access to those mount points.

I also see that /home/user has drwx–x—+ permissions. Does the whole mlocate thing discussed here require that I must also open the home folder permissions so that everyone can read? That would be quite inappropriate, no?

Others can read is the default for files and yes if you want to stop that you must change the permissions. But that can effect other things like locate.:open_mouth:

Check the actual file permission not just the directory

Speculating,
Add User “bacula” to Group “nobody”

As for your mlocate update issue,
Yes, permissions for what is to be updated is necessary.

Also, inspecting the contents of package mlocate.rpm and verified on my system…

  • You should have a file
/etc/cron.daily/mlocate.cron
  • The following file should exist which specifies what directories to index
/etc/updatedb.conf
  • The actual locate binary is
/usr/bin/locate
  • The binary to update the locate database is
/usr/bin/updatedb
  • Other files which include dependency libraries and documentation

TSU

Well, the easiest way would be to just run updatedb as root then as explained earlier.
This will make sure everything is in the database.

AFAIK mlocate does check what files/folders the current user is allowed to access, and only lists those.
That’s the main advantage over the old locate (which would have allowed every other user to find your files) and the reason why locate has been replaced with mlocate in the first place I think.

Yes.
I think also in his earliest posts that running “updatedb” did work for him but he was interested first in discovering why it seemed to him that auto daily updating didn’t work, and then that his NTFS partitions didn’t seem to be indexed.

TSU

I am a little confuse between this:

and this:

It seems there might be security implications in each of these two approaches?

As far as I understand the first one would require either adding each home dir user to group “nobody” or giving read access to others for user directories (not desired). Also I am not sure which processes run as user nobody and what else might happen.

AFAIK mlocate does check what files/folders the current user is allowed to access, and only lists those.
That’s the main advantage over the old locate (which would have allowed every other user to find your files) and the reason why locate has been replaced with mlocate in the first place I think.

Yes, I have just been reading this in the man page of updatedb. There is an option:


       -l, --require-visibility FLAG
              Set the “require file visibility before reporting it” flag in the generated database to FLAG.


              If FLAG is 0 or no, or if the database file is readable by "others" or it is not owned by nobody, locate(1) outputs the  database  entries even if the user running locate(1) could not have read the directory necessary to find out the file described by the database entry.


              If  FLAG is 1 or yes (the default), locate(1) checks the permissions of parent directories of each entry before reporting it to the invoking user.  To make the file existence truly hidden from other users, the database group is set to nobody and the database permissions prohibit reading the database by users using other means than locate(1), which is set-gid nobody.


**              Note that the visibility flag is checked only if the database is owned by nobody and it is not readable by "others".**

I made the following experiment:

  • Run updatedb as root with no extra options (supposing by default it will use flag 1 as per man page)
  • Checked the permission of the db file (it was 644)
  • Run “locate root” as normal user - I can see the contents of /root (which means the man page is wrong and by default flag is 0)
  • chown nobody: /var/lib/mlocate/mlocate.db
  • Run “locate root” as normal user - again I can see the contents of /root
  • chmod 640 /var/lib/mlocate/mlocate.db (as according to the documentation that is required in order the flag 1 to be respected) - same result

Then I tried explicitly to run “updatedb -l 1” as root and I see that it recreates the db file but this time the permissions are 640. So even when owned by nobody a normal user cannot use the locate command:

# locate root
locate: can not open `/var/lib/mlocate/mlocate.db': Permission denied


After adding my user to group nobody I was able to run “locate root” without seeing the files in “/root”.

This whole thing means that:

  1. The man page is not correct as the default is FLAG 0 (insecure), not 1 (secure)
  2. One is forced to use the first approach (adding each user to group nobody) with all its implications which I am not aware of
  3. The script /etc/cron.daily/mlocate.cron needs to be modified somehow in order to use explicitly FLAG 1

Can someone please give some information about these potential implications and advice on a proper way to solve this whole thing?

My desire is the files to be indexed properly (not necessary the files visible only to root) and each user to be able to see in locate output only what he is permitted to read according to the actual file system permissions.

IMO
When you start changing the permissions of large directory trees and/or changing the permissions of individual Users by adding to new Groups, particularly to non-login “special permission” groups like “nobody” you’re playing with fire. There is a strong likelihood you’ll end up making security mistakes which can allow compromise.

Instead,
if you want to extend the User to use an <application> it wouldn’t normally be able to use, you should use “sudo” instead, and grant specific capabilities through sudo(You don’t have to configure sudo to gain root permissions, that’s only the default in openSUSE and many other distros).

My suggestion to add the “Bacula” User to the “nobody” group was intended (hopefully) to extend the capability of a <non-login> User account(think of this kind of account as a Service account and not an actual human being) to additional <non-login> permissions which in theory should consistently not allow an interactive User account to suddenly gain special access to your system.

TSU