Search

Unix Permissions

0 views

Decoding the ls –l Output: Your First Look at Unix Permissions

When you run ls -l on a Linux or macOS system, the first column that greets you is the permission string. Each character in that string is a clue about the file’s type and its access rights. The typical output looks like this:

Prompt
total 154</p> <p>drwxr-xr-x 2 root sys 512 Apr 1 07:39 dir</p> <p>-rw-r--r-- 1 root sys 3515 Mar 6 13:28 disks.html</p> <p>-rw-r--r-- 1 root sys 7154 Mar 6 13:28 floppies.html</p>

The first character indicates the file type: a dash (–) for a regular file, d for a directory, l for a symbolic link, b for a block device, c for a character device, and a few other less common codes for sockets, FIFOs, and shared memory objects. The next nine characters are grouped into three sets of three: owner, group, and others. Each set contains r (read), w (write), and x (execute) or a dash if the permission is absent.

Beyond the string, ls -l shows the link count, owner name, group name, file size, modification time, and file name. Together, they provide a snapshot of who owns the file and how it can be used. When you first encounter this format, it may feel like deciphering a secret code, but with a few rules, it becomes straightforward.

To truly understand a file’s type, you can use the file command, which examines the file’s magic number and prints a human‑readable description. For example:

Prompt
$ file *.html</p> <p>disks.html: HTML document, UTF-8 Unicode text</p> <p>floppies.html: HTML document, UTF-8 Unicode text</p>

This confirms that the .html files are plain text. For special files, file can be even more revealing:

Prompt
$ file /dev/sda</p> <p>/dev/sda: block special (8/0)</p> <p>$ file /tmp/foo</p> <p>/tmp/foo: pipe</p>

By pairing ls -l with file, you gain a complete picture: type, ownership, and permission bits.

Because the permission string is the most visible representation of Unix security, it is worth taking the time to master it. Each character carries meaning that affects how users, programs, and services interact with the filesystem. In the next section we’ll dig deeper into what those bits actually allow you to do.

Owner, Group, and Others: Who Can Do What?

Unix permissions separate access into three distinct categories: the file’s owner, the group that owns the file, and everyone else. The string rwxr-xr-- is a good example: the owner has read, write, and execute rights; the group has read and execute rights; and others have only read rights. These rules apply to all files and directories, though the meaning of “execute” changes between them.

When a user logs in, the system associates the user’s numeric ID (UID) with a primary group ID (GID) and a set of supplemental groups. You can see which groups you belong to with id. For instance, if you run:

Prompt
$ id</p> <p>uid=1000(jane) gid=1000(jane) groups=1000(jane),27(sudo),30(dip)</p>

your primary group is jane, but you also have membership in sudo and dip. A file owned by sudo will allow you full control because you belong to that group. If you are not in the owner or group categories, the “others” set applies. That’s why shared files often use group permissions to grant collaboration while keeping the rest of the world in read‑only mode.

For executables, the execute bit is essential. A script like myscript.sh will only run if you have execute permission, even if you can read the file. That’s how Unix keeps scripts from being run accidentally or by unauthorized users. Changing the execute bit is as simple as chmod +x myscript.sh

When you look at a directory, the permissions work slightly differently. Read (r) lets you list the contents, while write (w) allows you to create or delete entries. Execute (x) is required to traverse into the directory and access the files it contains. A common misconception is that write permission alone lets you delete any file; it only does so if you also have execute permission on the directory. That subtlety keeps users from deleting files they shouldn’t touch.

Because Unix permissions are built on bitwise operations, you can combine them in many ways. A permission string of rw-rw-r-- means the owner and group can both read and write, while others can only read. This flexibility makes Unix a powerful tool for secure multi‑user environments. Later we’ll explore how special bits like setuid, setgid, and sticky alter the default behavior.

Special Bits: Setuid, Setgid, Sticky, and the Sticky File Flag

Three hidden flags can dramatically change how permissions work: setuid (s), setgid (g), and the sticky bit (t). These flags appear as a lowercase letter in the third slot of the permission string if the corresponding execute bit is set, or an uppercase letter if the execute bit is absent. Understanding them is critical for systems where programs need temporary elevation or where shared directories require controlled deletion.

The setuid flag is used on executable files to temporarily elevate the process’s UID to that of the file owner during execution. This is how the classic /usr/bin/passwd allows ordinary users to change their passwords: the binary runs as root, modifying the /etc/shadow file, while the user sees no privilege escalation. When setuid is active, the owner’s effective UID is used for the duration of the program. A typical permission string for a setuid binary looks like -rwsr-xr-x for owner execute and -rwxr-xr-x for group execute.

Setgid behaves similarly but affects the group ID. When applied to an executable, the process runs with the file’s group ID; when applied to a directory, new files created inside inherit the directory’s group ID instead of the user’s primary group. This is handy for project directories that need to maintain a shared group ownership, ensuring that teammates can read and write files without manually adjusting groups.

The sticky bit, visible as t, is almost exclusively used on directories. It restricts deletion and renaming of files within the directory to the file’s owner, the directory’s owner, or root. The classic example is the /tmp directory, which many users can write to but only delete files they created. Without the sticky bit, any user with write permission on the directory could remove any file, creating a security risk.

In addition to the three bits above, some filesystems support an “immutable” flag that prevents any changes to a file, even by root. Linux users can toggle this flag with chattr +i filename. The flag is especially useful for system configuration files that should never be altered accidentally. The reverse operation, chattr -i filename, re‑enables modifications.

Because these bits influence fundamental security behavior, administrators often audit them with find / -perm -4000 -type f -exec ls -l {} \; for setuid programs, or find / -perm -2000 -type d -exec ls -ld {} \; for setgid directories. Regular checks help maintain least‑privilege principles and prevent privilege escalation exploits.

Extended Attributes and Access Control Lists: Going Beyond Basic Permissions

Standard Unix permissions cover most use cases, but modern filesystems extend the model with attributes and access control lists (ACLs). Extended attributes store metadata that may affect file behavior or provide additional security flags. For example, on Linux ext4, the chattr +i command sets an immutable flag, while chattr +A enables the audit flag to log accesses.

Access control lists provide per‑user or per‑group permissions beyond the three‑category model. A typical ACL entry looks like user:alice:rwx or group:marketing:rw-. ACLs let you grant read permission to a specific user while keeping write access for the group, a scenario impossible with traditional bits. To manage ACLs, use commands like setfacl and getfacl. For instance:

Prompt
$ setfacl -m u:alice:r-- file.txt</p> <p>$ getfacl file.txt</p><h1>file: file.txt</h1> <h1>owner: root</h1> <h1>group: root</h1> user::rw-</p> <p>user:alice:r--</p> <p>group::r--</p> <p>mask::rw-</p> <p>other::r--</p>

ACLs are especially valuable in shared workspaces where multiple teams require different levels of access to the same files. However, they introduce complexity; forgetting which ACL entries exist can lead to unintended access. Regular audits with getfacl or tools like aclcheck help maintain clarity.

Filesystems such as FreeBSD’s UFS, NetBSD’s UFS, and macOS’s HFS+ also support extended attributes. macOS adds a “system immutable” flag, which only a superuser in single‑user mode can clear. On some systems, the chflags command toggles flags like uchg (user immutable) or schg (system immutable). These features provide extra layers of protection against accidental modifications or malicious tampering.

Because extended attributes and ACLs are optional, their support depends on the filesystem and kernel configuration. You can verify support with tune2fs -l /dev/sdX1 | grep "Default mount options" on ext4 or mount | grep to see if acl is enabled. If your environment requires fine‑grained access control, enable ACL support at mount time with the acl option.

Cross‑Platform Permission Mapping: When Unix Meets Windows

In many enterprises, Unix servers host files that Windows clients need to access through SMB (Samba) or NFS. Because Windows and Unix use different permission models, mapping them correctly is essential. Windows exposes attributes like Read‑Only, Hidden, System, and Archive, whereas Unix uses read, write, execute, and special bits. Only the Read‑Only attribute has a direct counterpart.

Samba bridges the gap by translating Windows attributes to Unix permissions. A Windows file marked Read‑Only becomes a Unix file with the owner’s execute bit cleared, making it read‑only for everyone. The Hidden attribute maps to the execute bit for the “others” group, allowing Windows clients to hide files from casual browsing. The System attribute maps to the group execute bit, and the Archive attribute maps to the user execute bit. Because Windows can set all these bits simultaneously, Samba may produce a Unix file with a complex permission string like -rwx--x--x

When designing a shared folder, decide whether to use Samba’s default mapping or customize the translation. Samba’s smb.conf offers options like map archive to attribute = never or map hidden to attribute = never to disable automatic mapping. These settings are helpful when you want Windows clients to ignore certain attributes or when you need to maintain strict Unix permissions regardless of Windows flags.

Another layer of complexity arises with user identity mapping. Samba can translate Windows user names to Unix UIDs via the winbind service, enabling proper ownership and group mapping. Without this, Samba may assign all files to a single user like nobody, causing permission headaches. Ensure your domain controller and winbindd.conf are configured correctly to maintain a one‑to‑one mapping.

Because SMB and NFS use different mechanisms for authentication and authorization, administrators should monitor both systems for mismatches. Tools like smbstatus for Samba and auditd for NFS can help detect unauthorized access attempts or permission drift.

Mastering chmod: From Octal Numbers to Symbolic Modes

The chmod command changes file permissions, and you can specify the new state in two ways: octal numbers or symbolic modes. Octal notation uses three digits, each representing owner, group, and others. The digits are the sum of the values for read (4), write (2), and execute (1). For example, chmod 755 file sets rwxr-xr-x permissions.

Symbolic modes are more expressive and easier to understand when you’re only changing a single bit. The syntax is chmod [who][operator][permissions]. The who field can be u (owner), g (group), o (others), or a (all). The operator can be + (add), (remove), or = (set exactly). The permissions field is a combination of r, w, and x. For instance, chmod g+w file adds write permission to the group.

Symbolic modes are especially handy in scripts or when applying changes recursively. For example, to give all users execute permission on a directory and its contents, you could run:

Prompt
$ chmod -R a+x /path/to/dir</p>

When you need to set special bits, include them in the symbolic expression. Setting setuid on a file would be chmod u+s file, while adding the sticky bit to a directory is chmod +t /tmp

Because the default umask determines the bits that are cleared when a file is created, chmod only ever adjusts the permissions after the initial creation. Therefore, it is often used in conjunction with umask adjustments to achieve desired default permissions.

Fine‑Tuning File Creation with Umask: The Hidden Permission Filter

The umask command shows the current mask, a number that tells the system which permission bits to clear when a new file or directory is created. Think of umask as a subtractive filter: the default permissions are calculated by subtracting the umask from the maximum set (0777 for directories, 0666 for files).

Most distributions set a default umask of 022, which means new files are rw-r--r-- and new directories are rwxr-xr-x. If you want newly created files to be readable and writable by the group, set umask 002:

Prompt
$ umask 002</p> <p>$ touch newfile</p> <p>$ ls -l newfile</p> <p>-rw-rw-r-- 1 user group 0 Mar 12 12:00 newfile</p>

When a program explicitly specifies permissions during file creation, it bypasses the default umask, but the umask still clears any bits the program does not request. For instance, if a program attempts to create a file with 0666 permissions while the umask is 002, the resulting permissions become 0664.

Some tools temporarily change the umask to 000 to guarantee full control over created files. For example, many installers run umask 000 before writing configuration files, ensuring that the owner has all rights regardless of the system’s default mask.

Administrators can set a global umask in shell configuration files like ~/.bashrc or /etc/profile. For multi‑user environments where you want stricter defaults, setting umask 077 will create files that are only accessible to the owner.

Because umask affects only file creation, not existing files, it is a powerful way to enforce policy without needing to audit and fix permissions manually. Coupled with ACLs and extended attributes, it forms part of a robust permission strategy.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles