Skip to content
ALB Wiki

Users and Permissions

This is an old revision of this page — revision 2 (2026-10-25 14:55:26 UTC). It may differ from the current revision.

Linux's security model is three questions applied to every file: who owns it, what group, and what do the three classes — owner, group, other — get to do? rwxr-xr-- is a contract printed in nine bits. This chapter reads the contract fluently, then goes deeper: the special bits, umask, the password machinery, and sudo's precise delegation of root.

Reading the contract

ls -l file
# -rwxr-xr-- 1 alice devs 4096 Jan 5 file
# ^ the leading char = type: - file, d dir, l symlink, c/b devices
#  rwx r-x r--  = owner rwx · group r-x · other r--

r=4, w=2, x=1 — modes as octal: 755 = rwxr-xr-x, 644 = rw-r--r--, 600 = rw-------. On directories x means enterable — a dir with rw but no x is unreadable-inside despite looking writable.

chmod 755 script.sh          # octal
chmod u+x script.sh          # symbolic — add exec to owner
chmod go-w file              # remove write from group+other
chmod -R 644 dir/            # recursive — usually a mistake on dirs+files mixed
chown alice file             # change owner
chown alice:devs file        # owner + group
chgrp devs file              # group only

The special bits — beyond rwx

Three extra bits change behavior fundamentally:

chmod 4755 program     # SETUID — runs as the FILE's owner (passwd does this)
chmod 2755 dir         # SETGID — runs as group / new files inherit group
chmod 1777 /tmp        # STICKY — only owner can delete (why /tmp is shared-safe)
ls -l passwd           # -rwsr-xr-x — the 's' marks setuid

setuid is how passwd lets you change your password in a file you don't own — it runs as root. It's also a security hazard — a setuid binary with a bug is privilege escalation waiting. find / -perm -4000 audits them.

umask — the default permissions

New files get 666 & ~umask, dirs 777 & ~umask:

umask                  # usually 022 → files 644, dirs 755
umask 077              # strict — 600/700, only for you
umask 022              # the sane shared default

Set it in ~/.profile — it's why your files arrive 644 not 777.

The account machinery

id alice               # uid, gid, all groups
whoami                 # effective user
groups                 # my groups
useradd -m -s /bin/bash alice   # create — -m home, -s shell
passwd alice           # set her password
usermod -aG wheel alice         # add to group — ALWAYS -a or you REPLACE the list
userdel -r alice       # remove + home
groupadd devs          # new group
gpasswd -d alice devs  # remove from group

/etc/passwd — the readable roster: name:x:uid:gid:gecos:home:shell. /etc/shadow — the hashes, root-only: name:$6$hash:... with aging fields. /etc/group — group:x:gid:members. The x in passwd is the shadow split — passwords moved out of the world-readable file long ago.

su vs sudo — two kinds of becoming

su -                   # become root — LOGIN shell, root's env
su - alice             # become alice fully
sudo command           # run ONE command as root — logged, delegated
sudo -i                # root login via sudo
sudo -u alice cmd      # as any user
sudo !!                # rerun last command as root — the muscle memory

sudo is configured in /etc/sudoers — edit only with visudo (it syntax-checks before saving; a broken sudoers locks everyone out). The delegation grammar: alice ALL=(ALL) ALL, or %wheel ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx — precise commands, precise users, optionally passwordless. su shares the root password; sudo shares nothing — it logs who ran what.

File ownership inside /proc and friends

A process carries real uid, effective uid, filesystem uid — ls -l /proc/PID/ shows the process's view. Files created follow the effective uid and the process's umask — which is why a daemon's files land with its service user's name on them.

The mode bits — the complete grammar

# symbolic — who, op, what
chmod u+x file        # user +execute
chmod g-w file        # group -write
chmod o=r file        # other =read-only
chmod a+r file        # all +read
chmod u+s program     # setuid
chmod g+s dir         # setgid
chmod +t dir          # sticky
chmod u=rwx,g=rx,o= file   # combined

# octal — the number language
chmod 644 file        # rw- r-- r--  = 6 4 4
chmod 755 file        # rwx r-x r-x
chmod 700 dir         # rwx --- ---   (private)
chmod 600 key         # rw- --- ---   (keys/secrets)
chmod 640 conf        # rw- r-- ---
chmod 664 shared      # rw- rw- r--
chmod 2775 sharedir   # setgid + 775 — the shared-dir formula
chmod 4755 program    # setuid — runs as owner
chmod 1777 /tmp       # sticky + world — /tmp's magic
chmod 751 dir         # rwx r-x --x   — group-traversable, world-blocked

Reading the bits: r=4 w=2 x=1 per triad. find / -perm -4000 finds setuid; find / -perm -0002 world-writable. chmod --reference=other file clones another's mode.

/etc/passwd + shadow + group — the schema

# /etc/passwd — world-readable roster:
#   name : x : uid : gid : gecos : home : shell
#   alice:x:1000:1000:Alice:/home/alice:/bin/bash

# /etc/shadow — root-only hashes:
#   name : $6$salt$hash : lastchange : min : max : warn : inactive : expire
#   alice:$6$salt$...:19500:0:99999:7:::

# /etc/group — groups:
#   name : x : gid : members
#   devs:x:1001:alice,bob

# $6$ = SHA-512 · $y$ = yescrypt · $1$ = MD5 (dead) · $2b$ = bcrypt

vipw/vigr edit passwd/group safely (locking); pwck/grpck sanity-check them. getent passwd alice, getent group devs, getent shadow alice read through NSS (covers LDAP/AD sources too).

The user/group administration surface

useradd -m -s /bin/bash -G wheel,devs alice    # -m home -s shell -G groups
useradd -r -s /sbin/nologin svcacct            # system account — no login
usermod -aG devs alice                          # append to groups — ALWAYS -a
usermod -L alice / -U alice                     # lock/unlock
usermod -s /sbin/nologin alice                  # kill login without deleting
usermod -d /newhome -m alice                    # move home
userdel -r alice                                # remove + home + spool
passwd alice                                    # set password
passwd -l alice                                 # lock the password
chage -l alice                                  # the aging policy
chage -M 90 alice                               # 90-day max
groupadd devs; gpasswd -a alice devs; gpasswd -d alice devs
newgrp devs                                     # switch primary group live

The classic traps: -G without -a replaces all groups; -r system accounts get low UIDs; /sbin/nologin is a shell that refuses — for service accounts.

su vs sudo — the deep difference

su -             # full root login — env, cd ~, everything
su - alice       # become alice — her env, her shell
su alice         # partial — keeps YOUR env, her identity
su -c 'cmd' alice # one command as alice

sudo cmd          # one command as root — your password, logged
sudo -i           # root login via sudo
sudo -s           # root shell, your env
sudo -u alice cmd # as any user
sudo -l           # YOUR allowed commands
sudo -v           # validate/refresh the timestamp
sudo -k           # kill the timestamp — force re-auth
sudo !!           # the classic muscle memory
sudoedit file     # edit-as-root without a root-owned file
visudo            # THE only way to edit /etc/sudoers

sudo -l shows your delegated rights; visudo syntax-checks before saving (a broken sudoers file locks everyone out). The delegation grammar — alice ALL=(root) /usr/bin/systemctl restart nginx — user, hosts, target-identity, commands. %wheel prefixes groups.

PAM — the auth layer

ls /etc/pam.d/              # per-service policies — login, sshd, sudo...
cat /etc/pam.d/sshd         # what sshd auth requires
# auth|account|password|session  required|requisite|sufficient|optional  module

PAM (Pluggable Authentication Modules) sits under every login — pam_unix (passwords), pam_nologin, pam_securetty, pam_faildelay, pam_faillock (lockout), pam_umask, pam_env. The auth/account/password/session stack order is the policy.

Groups — the shared-access mechanism

A file's group is the primitive for shared access: chgrp devs repo/; chmod g+w repo/ — every devs member can write. Setgid on a directory makes new files inherit the directory's group — the shared-workspace idiom: chmod 2775 repo/ keeps devs ownership propagating downward.

ACLs — when 9 bits aren't enough

setfacl -m u:alice:rw file       # alice specifically gets rw
getfacl file                   # the access-control list
setfacl -m d:u:devs:rwx dir    # default ACL — new files inherit
ls -l file                     # the '+' after the mode = ACLs present

When a file needs different permissions for several specific users — beyond owner/group/other — ACLs carry it. Most systems never need them; the day you do, they're indispensable.

Capabilities — root's powers, unbundled

Traditional root is all-or-nothing; capabilities split it:

setcap 'cap_net_bind_service=+ep' server   # bind :80 without root
getcap server

cap_net_bind_service, cap_setuid, cap_sys_admin — the modern way to grant a process one privilege instead of all.

Where permissions go wrong

SymptomCause
"Permission denied" on a file you ownDirectory missing x — can't traverse
chmod -R 755 broke ssh keys~/.ssh must be 700, keys 600
sudo asks for password constantlyNOPASSWD: absent, or wrong sudoers line
usermod wiped group membershipForgot -a — -G REPLACES
New files wrong groupMissing setgid on the shared dir
find / -perm -4000 surprisesSetuid binaries you didn't expect — audit
Script "can't execute" despite 755Filesystem mounted noexec — /tmp often is

Exercises

  1. stat a file — read all three timestamps and the mode.
  2. umask 077; touch f then umask 022; touch g — compare.
  3. find /usr/bin -perm -4000 — inventory the setuid binaries; identify three.
  4. Create a shared dir with setgid; prove new files inherit the group.
  5. visudo-safe edit: grant your user NOPASSWD for one specific command.
  6. Explain why passwd needs setuid — and why it must be bug-free.

See also

Categories: Handbook · Linux · Linux Handbook · Security
This page was last edited 2026-10-25 14:55:26 UTC by ALB Team. What links here