chmod Basics

default

chmod = change file modes

OctalOwnerGroupOthersSymbolic
777rwxrwxrwxa=rwx
666rw-rw-rw-a=rw
555r-xr-xr-xa=rx
444r--r--r--a=r
333-wx-wx-wxa=wx
222-w--w--w-a=w
111--x--x--xa=x
000---------a=

rwx rw- r-x = chmod 765
421 42- 4-1 = 765
_7_ _6_ _5_ = chmod u=rwx,g=rw,o=rx

After chmoding a file you can use ls -l to view the permissions.

Using the above chart you can combine permissions.

Add -v for verbose: chmod -v 700 someFile
Verbose mode shows: filename, before and after chmod permission changes.
On freebsd use -vv, else it will just show filenames that changed.

chmod 731 test.py = rwx-wx--x
chmod 644 test.txt = rw-r--r--
The numbers are octal.
Owner = user that created the file
Group = users in the same group as owner
Others = the rest of the users on the system

You can also change permissions without numbers:
u g o a (user group other all)
+ - = (add remove exact)
r w x (read write execute)

chmod u+x test.lisp = add execute perm for user who created file
chmod go-rwx = remove read write execute perms from group and all other users
chmod u=rwx = sets rwx for user and removes all from everything else

chmod u=rwx,g=wx,o=x someDirectory # sets to: 731 = rwx-wx--x
chmod u=rw,g=r,o=r someFile # sets to: 644 = rw-r--r-

# sticky, setuid, setgid bit can be changed octally, by prefixing the other three with: 1-7
# sticky (1 or +t) = only owner/superuser can delete or rename files in sticky directory
# setuid (2 or +s) = when executing, run with owner's permissions, not current user's
chmod 1777 someDirectory # 1000 = sticky
chmod 2775 someDirectory # 2000 = setgid
chmod 4770 someFile or someDir # 4000 = setuid
# all three with 4+2+1 = 7
chmod 7642 some file

chmod u+t someDir # make directory sticky
chmod u+s someFile # add setuid bit for user

# Example of sticky
# Use: everyone should be able to write to /tmp, but not rename or delete others files.
stat -c "%A %a %n" /tmp
drwxrwxrwt 1777 /tmp # Notice the t at end of hr output, and the 1 in front octal output.
# stat = display file or file system status
# -c or --format = use given format commands instead of defaults
# %A = human readable bit permissions
# %a = octal bit permissions
# %n = file name
# Man stat, for more info

# On freebsd stat is different:
stat -f "%Sp %Mp%Lp %N" sticky/
drwsrwxrwt 5777 sticky/
# %Sp = string permissions
# %Mp = suid, sgid, sticky
# %Lp = user, group, other
# %Hp = would add file type, they stand for high, medium, low permission bits
# %N = filename

# If you don't mind longer format and only want octal on freebsd use:
stat -f "%p" stickyFolderName
stat -f "%Op" ../sticky
45777
# %p = display type and permissions, permissions are last 4
# this is like: "%Hp%Mp%Lp"
# %Op = same as above, but explicitly calling for octal

stat -f "%Sp" stickyFolderName
drwsrwxrwt
# %Sp = display mode of file as string: like: ls -ld

# If you dont care about octal, this is more portable:
ls -ld /tmp
drwxrwxrwt

Example of setuid:
# Use: passwd, sudo, doas have suid set, in the case of passwd,
# that command effects: /etc/shadow, but a normal user can
# not modify shadow file, the suid runs passwd with root's
# permissions.
# (not useful on directories)
stat -c "%A %a %n" `which passwd`
-rwsr-xr-x 4755 /usr/bin/passwd # Notice s instead of x on users execute bit

ls -ld `which sudo` | awk '{print $1 " " $NF}'
-rwsr-xr-x /usr/bin/sudo

In freebsd stat is different, and may be using doas rather than sudo:
stat -f "%Sp %Mp%Lp %N" `which passwd`
-r-sr-xr-x 4555 /usr/bin/passwd

ls -ld `which doas` | awk '{print $1, $NF}'
-rwsr-xr-x /usr/local/bin/doas

# Setgid on file is similar to setuid, except the s is on the group's
# exectable bit, instead of user. It runs a file with the groups
# privileges, instead of the current user's.
chmod g+s someFile
# Setgid on folder makes any files created in folder to have the same
# group owner as the folder, not the group of the users that create files in
# the folder.
chmod g+s someDirectory
# Find files with suid in /usr/bin and /var/log on linux
find /usr/bin /var/log -perm -2000 -printf '%M %m %p\n' 2> /dev/null
# -rwxr-sr-x 2755 /usr/bin/wall
# -rwxr-sr-x 2755 /usr/bin/write
# -rwsr-sr-x 6755 /usr/bin/unix_chkpwd # example of both suid, sgid
# drwxr-sr-x 2755 /var/log/journal
# drwxr-sr-x 2755 /var/log/journal/a43e209e957f409bb4ca7eefc59d2654
# drwxr-sr-x 2755 /var/log/journal/remote

# Find files with suid set in /usr/bin on freebsd
# fbsd find does not have -printf
find /usr/bin -perm -2000 -exec stat -f '%Sp %Mp%Lp %N' {} +;
# -r-xr-sr-x 2555 /usr/bin/wall
# -r-xr-sr-x 2555 /usr/bin/write
# -r-sr-sr-x 6555 /usr/bin/lpq # example of both suid, sgid being set
# -r-xr-sr-x 2555 /usr/bin/btsockstat
# -r-sr-sr-x 6555 /usr/bin/lpr
# -r-sr-sr-x 6555 /usr/bin/lprm
# -r-xr-sr-x 2555 /usr/bin/netstat

default