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
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
SYNOPSIS
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
OPTIONS
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--
Fields
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 myscript.sh 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.
#!/bin/bash
# Loop through each folder in /volume1/photo
for year_dir in /volume1/photo/*/
do
# 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[@]}"
do
path="/volume1/photo/$year/$user"
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-- ;;
esac
synoacltool -del-archive "$path" is_inherit
fi
done
# Apply permissions for public months
for month in "${public_months[@]}"
do
path="/volume1/photo/$year/$month"
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
fi
done
else
echo "Skipping non-year directory: $year_dir"
fi
done