Mac OS X Catalina - NFS File Access Behavior in CRON or Launchd

I'm really struggling here, and I think this is a new effect of upgrade to Catalina. I have an automounted NFS directory that contains a file I want to periodically copy to my Mac's local file system. I have a script that does this, and it worked beautifully before Catalina upgrade. If I run the script manually (as root) it's all good. If I run the script as part of a scheduled job it fails. I've tried launching the script in root owned cron job, and I've tried using Launchd. Both fail the same way.

My script:

#!/bin/sh

if [ -f /System/Volumes/Data/nfs/hosts ]
then
    cat /etc/hosts.base /System/Volumes/Data/nfs/hosts > /etc/hosts
fi

/System/Volumes/Data/nfs is an NFS share coming off a Synology NAS.

The [ -f ...] part works fine. It can successfully determine if the hosts file exists in the NFS directory. But the cat command fails reading the hosts file. Again, if I run the script manually it all works fine. It only fails if the script is launched from cron or launchd.

File permissions:

brians-mbp:etc root# ls -la /System/Volumes/Data/nfs/hosts
-rwxrwxrwx 1 1024 _lpoperator 2393 Feb 8 14:29 /System/Volumes/Data/nfs/hosts

I've tried fiddling with owner and group, no effect. I've tried different approaches of mounting the NFS drive (automount, fstab, etc), no effect. I've tried different directories, different filenames, etc, no effect. I've tried using different shells in the script (sh, zsh, ...), no effect.

I've tried to find whether Catalina introduced some new ACL mechanisms but can't find anything other than gripes about how Apple changed directory structure in Catalina. But the fact that the script runs just fine if run manually tells me the permissions/ACLs must be ok.

Any ideas?

Brian

Hello

1)
Are you using variables within the cron script (or is it really as hardcoded as you describe)?
If so, this would be the cause of error, as CRON runs without an 'environment' (AFAIK).

2)
Did you add the job to the root's cron, or to your own?

3)
I dont know /etc/hosts.base ; is that a Mac (or customized) thing?
But since you said the script runs fine when executed manualy, this cant be it.

hth

Thanks hth.

  1. The script is hard coded, no environment variables.

  2. Yes. sudo su - then crontab -e. I've also tried it using Mac OS X's Launchd, which is their cron replacement since they do state that they are deprecating cron. But it didn't make a difference.

  3. I should have been more clear about the behavior. The problem is that the hosts files in the NFS dir can't be read. The [ -f .../hosts] test works fine, so the script can access the NFS directory and see that the file exists, but the cat command can't read the actual file. The hosts.base is moot. If I just simply try to "cat /.../nfs/hosts > /etc/hosts" then I end up with a 0 sized /etc/hosts file.

Somehow Mac OS X Catalina is executing the script in some sort of environment differently depending on whether it is launched manually, or from cron/launchd.

:smiley:
hth = hope this helps
:smiley:

I'm no Mac user, so I cant tell from accurate (to you) practice.
But once I've mounted a NAS path, I could always read files - once I was able to see the directories.

I might not have had write access, but read was always possible when mounted successfully as root (usualy using CIFS, not sure if that applies).

Also, have a re-try with just su as I'm not sure wether or not you had passed that dash, which would make su 'adapt' partialy to the env of the user (kind of, lost in translation and memory).

Comes to mind, check your 'mount nas' options, they might 'provoke' list only.

Also, forgot to say earlier, please use ICODE (Icon: >_) for 'on line' commands, and 'CODE' tags (Icon: </>) for multi-line output, such as your initial post.

hth

Agreed. Also, check the access rights set on the NAS end. I'm no MAC user either but perhaps your upgraded OS is checking acess rights on the NAS that it wasn't checking before.

Well, I'm about to give up. I've gone through every single permission and access rights option on the NAS, no luck. Again, what completely confuses me is that I can run the script manually from the shell and everything works perfectly. So I know that the NFS directory is mounted, and that root user can read the files in it. But as soon as it's a cron job or a launchd job that runs the script it can see the file, but can't read it.

The log simply says:

cat: /System/Volumes/Data/nfs/hosts: Operation not permitted

Without a doubt the upgrade to Catalina resulted in scripts being run within the context of cron or launchd to use a different environment than that of the command line. This approach of mine works on ALL my other Linux, *nix (SunOS, Solaris, HP-UX, AIX, Linux), heck, even OpenVMS, but no longer on Mac OS X. Grrrrr....

Just showing that cat doesnt work, is of no help while we already know that you do not have read access - for some reason.

Without knowing how you actualy mounted your NAS, we cant help you further.
Let me rephrase.

By the sounds of your posts, I take it you tried with chmod ?
Instead, show us the mount command used or the according (if applicable) /etc/fstab line.

I've tried about 50 combinations, in the current and most simple form I use /etc/fstab

#
# Warning - this file should only be modified with vifs(8)
#
# Failure to do so is unsupported and may be destructive.
#
cady:/volume1/nfs       /System/Volumes/Data/nfs        nfs     rw

But in an attempt to try a lot of different combinations quickly I just used mount commands directly. Here's a sampling from my history.

mount cady:/volume1/nfs /System/Volumes/Data/nfs
mount_nfs -o resvport cady:/volume1/nfs /System/Volumes/Data/nfs
mount_nfs -o noacl cady:/volume1/nfs /System/Volumes/Data/nfs
mount_nfs -o nolock cady:/volume1/nfs /System/Volumes/Data/nfs
mount_nfs -o nfsvers=4 cady:/volume1/nfs /System/Volumes/Data/nfs
mount_nfs -o nfsvers=2 cady:/volume1/nfs /System/Volumes/Data/nfs
mount -o rw,sync,no_root_squash,no_subtree_check,insecure cady:/volume1/nfs /System/Volumes/Data/nfs
...
...

Using either mount commands directly, or using auto_master / auto_nfs , or /etc/fstab I can easily get the NFS drive mounted, and the permissions and ownership is correct. From a shell I can copy files to/from the local system to the NFS mount without troubles. The logs on the NFS server show no errors. I've already posted the unhelpful error log from the client machine.

I've tried lots of different combinations of owner/group/permissions via chown, chgrp and chown. Currently sitting at:

brians-mbp:etc root# ls -la /System/Volumes/Data/nfs/hosts
-rwxrwxrwx 1 1024 _lpoperator 2393 Feb 8 14:29 /System/Volumes/Data/nfs/hosts

I was hoping somebody familiar with how Mac OS X specifically creates the environment in which Launchd or cron jobs run could shed some light. Even though root has access to the files, and the Launchd or cron job is owned by root, it somehow isn't executed with normal root rights.

Who is executing the job? in other words what cron user?
But to me it is more Synology side you should look: After upgrade did you reinit passwords on your mac? did you sync after the Synology?...

https://mariushosting.com/connection-problem-between-synology-nas-and-macos-catalina/

Also, have you checked for a firmware update for the Synology NAS?

SOLVED. As suspected, since accessing the NFS mount from a shell, or from a shell script manually worked fine, but when accessing via shell script launched by either cron or launchd didn't work, it was clearly something that Apple introduced in Catalina related to access permission layers in that specific context. I finally found on another forum a lengthy rant about Apple changing the default access rights of the parent process that launches launchd jobs in the Catalina upgrade. Those access rights are inherited by child processes, so even though script was being run as root, it didn't get all root privileges. The solution was to restore the access rights of the parent to that of the previous Mac OS version (done via the GUI. System Preferences->Security and Privacy->Full Disk Access->re-enable sh). I'm sure this was done by Apple to tighten security for a mainly consumer user base who may not be careful about what they connect to on the network.

2 Likes

Thanks for posting the solution.