For quite some time, I’ve been using Synology PhotoStation to manage all my family photos. Since I’m not the only user—my children also use the app—I thought it might be a good idea to set some permissions on the different folders. In general, I use three different groups: full control, read-write, and read-only. This way, my kids can access all shared family photos but can’t accidentally delete them. Setting access permissions within Synology Photos is somewhat limited, so I had to reorganize my folder structure to fulfill my needs. However, in the end, it worked out very well.

Last week, I decided to move over some additional photos and reorganize parts of my original folder structure. Thinking it would be quicker than using the web GUI, I accessed my photo share through SMB. Immediately, I noticed something wasn’t right. Folders could not be renamed, data couldn’t be moved, and so on. When I looked at the Windows ACL permissions, I noticed they were different from the permissions set in Synology Photos. In my case, most permissions were inherited from the root photos folder.

That was an eye-opener—different permissions between the Photo and SMB apps. So, I needed to change my Windows ACL permissions to match the permissions set in Synology Photos. My first thought was to use PowerShell to modify the existing permissions on all my folders at once. Unfortunately, that wasn’t an option; the Windows ACL permissions on Synology folders can’t be changed using PowerShell

How can I manage ACL settings on my Synology NAS?

The Synology documentation only explains how to set permissions through their web GUI, which wasn’t an option for me due to the many folders and varying permissions set everywhere. After some Googling, I discovered a Synology tool called “synoacltool” that could do the trick. The downside is that it’s very undocumented. The built-in help (synoacltool -h) is extremely limited, so I had to do a lot of trial and error.

Usage: synoacltool

        synoacltool -h
        synoacltool -check PATH [ACL Perm]
        synoacltool -get PATH
        synoacltool -getace PATH
        synoacltool -get-perm PATH USERNAME
        synoacltool -add PATH [ACL Entry]
        synoacltool -replace PATH [ACL Entry Index] [ACL Entry]
        synoacltool -get-archive PATH
        synoacltool -set-archive PATH [ACL Archive Option]
        synoacltool -del-archive PATH [ACL Archive Option]
        synoacltool -del PATH [ACL Entry Index]
        synoacltool -del PATH
        synoacltool -copy PATH_SRC PATH_DST
        synoacltool -set-owner PATH [user|group] NAME
        synoacltool -set-eadir-acl PATH
        synoacltool -enforce-inherit PATH
        synoacltool [-stat|-cstat|-fstat|-lstat|-utime] PATH

        -h: show help
        -check: check acl permission of file
        -get: get syno acl of file
        -getace: get syno ACEs with uid/gid of file
        -get-perm: extract windows permission from acl or linux permission
        -add: add syno ace into file
        -replace: replace specified ace by index number
        -del: delete syno acl of file
        -get-archive: get ACL archive bit
        -set-archive: set ACL archive bit
        -del-archive: delete ACL archive bit
        -stat, -cstat, -lstat, -fstat: get stat/archive bit
        -utime: set current time into file
        -copy: copy ACL from source to destination, only works when ACL exists
        -set-eadir-acl: set ACL for EA dir
        -enforce-inherit: enforce ACL inheritance

        ACL Entry Index: >= 0
        ACL Option: [inherit|single]
        ACL Archive Option: is_inherit,is_read_only,is_owner_group,has_ACL,is_support_ACL
        ACL Entry: [user|group|owner|everyone|authenticated_user|system]:name:[allow|deny]:permissions:inherit mode

                Example: user:root:allow:rwx-d---RWc--:fd--
                Example: owner:*:allow:rwx-d---RWc--:fd--

                        name: user/group name
                        ACL Perm: rwxpdDaARWcCo
                                 r: (r)ead data
                                 w: (w)rite data (create file)
                                 x: e(x)ecute
                                 p: a(p)pend data (create dir)
                                 d: (d)elete
                                 D: (D)elete child (only for dir)
                                 a: read (a)ttribute (For SMB read-only/hidden/archive/system)
                                 A: write (A)ttribute
                                 R: (R)ead xattr
                                 W: (W)rite xattr
                                 c: read a(c)l
                                 C: write a(c)l
                                 o: get (o)wner ship

                        inherit mode: fdin
                                 f: (f)ile inherited
                                 d: (d)irectory inherited
                                 i: (i)nherit only
                                 n: (n)o propagate

First, I used “synoacltool -get /volume1/photo/xxxx” to query the existing folder permissions.

Next, I tried changing the existing permissions to match my requirements using the command: “synoacltool -add /volume1/photo/xxxx group:photos-xxx-admin:allow:rwxpdDaARWcCo:fd–“. As shown in the screenshot below, the admin group is now visible at both level 0 and level 1. Level 0 represents the explicit permission, while level 1 represents the inherited permission.

This is starting to look good. Now, let’s try to remove the inherited permissions. In the above screenshot, you’ll see Archive: is_inherit. Within the limited help file, I saw the command synoacltool -del-archive PATH [ACL Archive Option]. Let’s try removing the inheritance with: “synoacltool -del-archive /volume1/photo/xxxx is_inherit”

Let’s query the current folder permissions:

Now that I discovered how to change the permissions and break the inheritance, I decided to reset all folder permissions through the Synology web GUI from the top-level folder. Afterwards, I set all desired permissions using synoacltool.

My photo (root) folder contains a folder for each year, for example 2023, 2024, etc. Within that year folder there’s a folder for each month and several personal folders, like user1, user2.

I wrote a bash script to update all desired permissions, which can be run from the Synology CLI. Just to give you a idea how it could look like, this is an example script. Don’t forget to use the command chmod +x after creating or modifying the script to ensure it can be executed. This command sets the executable permission for the owner of the file, allowing them to run the script.


# Loop through each folder in /volume1/photo
for year_dir in /volume1/photo/*/
  # Strip trailing slash and extract the year part from the path
  year=$(basename "${year_dir%/}")
  # Check if the year is a number
  if [[ "$year" =~ ^[0-9]{4}$ ]]; then
    echo "Processing year: $year"

    # Define the common parts of the paths and permissions
    private_users=("User1" "User2")
    public_months=("01 - January" "02 - February" "03 - March" "04 - April" "05 - May" "06 - June" "07 - July" "08 - August" "09 - September" "10 - October" "11 - November" "12 - December")

    # Apply permissions for private users
    for user in "${private_users[@]}"
      if [ -d "$path" ]; then
        synoacltool -add "$path" user:PhotoStation:allow:rwxpdDaARWcCo:fd--
        synoacltool -add "$path" group:photos-xxx-admin:allow:rwxpdDaARWcCo:fd--
        case $user in
          "User1") synoacltool -add "$path" group:photos-zzz-rw:allow:rwxpd-aARWc--:fd-- ;;
          "user2") synoacltool -add "$path" group:photos-yyy-rw:allow:rwxpd-aARWc--:fd-- ;;
        synoacltool -del-archive "$path" is_inherit

    # Apply permissions for public months
    for month in "${public_months[@]}"
      if [ -d "$path" ]; then
        synoacltool -add "$path" user:PhotoStation:allow:rwxpdDaARWcCo:fd--
        synoacltool -add "$path" group:photos-xxx-admin:allow:rwxpdDaARWcCo:fd--
        synoacltool -add "$path" group:photos-xxx-rw:allow:rwxpdDaARWc--:fd--
        synoacltool -add "$path" group:photos-xxx-ro:allow:r-x---a-R-c--:fd--
        synoacltool -del-archive "$path" is_inherit
    echo "Skipping non-year directory: $year_dir"

Post Navigation