How to apply a single permission recursively?

I want to give a group full control on a dataset and all nested files and folders. The dataset has SMB/NFSv4 ACLs.

This directory has owner@ and group@ values that do not align with directories within the dataset, therefore I cannot simply add the ACL for the group and choose “Apply permissions recursively” because it will overwrite the owner@ and group@ for nested files and folders. I can’t see a way within the GUI to apply just a single ACL recursively and ignore the existing ACLs.

I also tried using the CLI to set the permissions using the following command:

root@truenas[~]# midclt call filesystem.setacl '{                                                                                                                                                                                                                                                   
  "path": "/mnt/path/to/dataset",
  "dacl": [
    {
      "tag": "GROUP",
      "type": "ALLOW",
      "perms": {
        "BASIC": "FULL_CONTROL"
      },
      "flags": {
        "BASIC": "INHERIT"
      },
      "id": 100001106
    }
  ],
  "options": {
        "recursive": true,
        "traverse": true
  },
  "uid": null,
  "gid": null,
  "acltype": "NFSV4"
}'

I guess this is formatted incorrectly? Not sure how, I tried to reference this: filesystem.setacl — TrueNAS API v25.04.1 documentation

In the audit log I just had the following:

{
  "success": false,
  "method": "filesystem.setacl",
  "params": [
    {
      "path": "/mnt/path/to/dataset",
      "dacl": [
        {
          "tag": "GROUP",
          "type": "ALLOW",
          "perms": {},
          "flags": {},
          "id": 100001106
        }
      ],
      "options": {
        "recursive": true,
        "traverse": true
      },
      "uid": null,
      "gid": null,
      "acltype": "NFSV4"
    }
  ],
  "description": "Filesystem set ACL /mnt/path/to/dataset",
  "authenticated": true,
  "authorized": true
}

The perms and flags objects are empty, is it not reading these values correctly from my command? It seems this might be the case because I tried with NFS4ACE_AdvancedFlags and they then appeared correctly in the audit log (perms remained empty). But I want to use NFS4ACE_BasicFlags, and the API implies this is possible.

Any ideas?

Are we allowed to “bump” here? :slight_smile:

Seems to me this is pretty important functionality, hope it is possible?

Normally you would be able to modify (instead of replace) ACLs with setfacl -m, but you shouldn’t use setfacl in TrueNAS - I believe you’re expected to use nfs4xdr_setfacl instead.

nfs4xdr_setfacl also offers an -m option, but it’s worded differently and I am not sure if it’s functionally equivalent. Perhaps that is something you can look into yourself?

1 Like

Thanks for the tip. I wasn’t aware of that command (just a beginner with TrueNAS), so it set me on the right track.

I made a test dataset and created a file within, here are the permissions as seen in TrueNAS:

Using the nfs4xdr_getfacl command:

root@truenas[~]# nfs4xdr_getfacl /mnt/slow/test
# File: /mnt/slow/test
# owner: 0
# group: 0
# mode: 0o40755
# trivial_acl: false
# ACL flags: none
            owner@:rwxpDdaARWcCos:fd-----:allow
            group@:r-x---a-R-c---:fd-----:allow
         everyone@:r-x---a-R-c---:fd-----:allow
root@truenas[~]# nfs4xdr_getfacl /mnt/slow/test/test.txt
# File: /mnt/slow/test/test.txt
# owner: 0
# group: 0
# mode: 0o100755
# trivial_acl: false
# ACL flags: none
            owner@:rwxpDdaARWcCos:------I:allow
            group@:r-x---a-R-c---:------I:allow
         everyone@:r-x---a-R-c---:------I:allow

Based on the info provided when running nfs4xdr_getfacl -H and nfs4xdr_setfacl -H, and after testing by adding the --test option, I ran this:

root@truenas[~]# nfs4xdr_setfacl -R -a u:administrator@home:rwxpDdaARWcCos:fd:allow 4 /mnt/slow/test
ace_index: 4, mod_string: u:administrator@home:rwxpDdaARWcCos:fd:allow
ace_index: 4, mod_string: u:administrator@home:rwxpDdaARWcCos:fd:allow

(administrator@home is a user on my domain to which my TrueNAS is joined)

Checking from the UI:

And creating a new file and checking ACL:

root@truenas[~]# touch /mnt/slow/test/test2.txt
root@truenas[~]# nfs4xdr_getfacl /mnt/slow/test/test2.txt                                                      
# File: /mnt/slow/test/test2.txt
# owner: 0
# group: 0
# mode: 0o100755
# trivial_acl: false
# ACL flags: none
            owner@:rwxpDdaARWcCos:------I:allow
            group@:r-x---a-R-c---:------I:allow
         everyone@:r-x---a-R-c---:------I:allow
user:administrator:rwxpDdaARWcCos:------I:allow

And just for good measure:

root@truenas[~]# midclt call filesystem.getacl /mnt/slow/test | jq
{
  "path": "/mnt/slow/test",
  "user": null,
  "group": null,
  "uid": 0,
  "gid": 0,
  "acltype": "NFS4",
  "acl": [
...
    {
      "tag": "USER",
      "type": "ALLOW",
      "perms": {
        "BASIC": "FULL_CONTROL"
      },
      "flags": {
        "BASIC": "INHERIT"
      },
      "id": 100000501,
      "who": null
    }
  ],
...

So yes, it works perfectly :slight_smile:

TL;DR:

Use nfs4xdr_setfacl with -R option for recursive, e.g.:
root@truenas[~]# nfs4xdr_setfacl -R -a u:myuser:r-x---a-R-c---:fd:allow /path/to/file

1 Like