Права доступа и атрибуты файлов¶
Модель прав доступа¶
Права доступа в Linux определяют, кто может что делать с файлом. Каждый файл имеет три набора прав:
- u (user/owner) — права владельца файла;
- g (group) — права группы;
- o (other) — права всех остальных.
Каждый набор состоит из трёх битов:
| Бит | Символ | Восьмеричное | Значение |
|---|---|---|---|
| r | read | 4 | Чтение содержимого файла |
| w | write | 2 | Запись / изменение файла |
| x | execute | 1 | Выполнение файла (или вход в директорию) |
Посмотреть права:
ls -l file.txt
# -rw-r--r-- 1 alice devs 1024 Jan 14 12:00 file.txt
# ^^^ ^^^ ^^^
# uuu ggg ooo
stat -c "%a %n" file.txt # восьмеричный формат: 644 file.txt
Расшифровка rw-r--r-- (644): владелец — чтение+запись (6), группа — только чтение (4), остальные — только чтение (4).
Структура mode_t: биты прав и специальные биты¶
mode_t (16 бит):
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
┌───┬───┬───┬───┬────┬────┬────┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ тип файла │SUID│SGID│Stky│ r │ w │ x │ r │ w │ x │ r │ w │ x │
└───┴───┴───┴───┴────┴────┴────┴───┴───┴───┴───┴───┴───┴───┴───┴───┘
(S_IFMT) │ │ │ └───────────┘ └───────────┘ └───────────┘
│ │ │ user(u) group(g) other(o)
│ │ │
│ │ └── Sticky (01000) — /tmp: удаляет только владелец
│ └─────── SGID (02000) — запуск от имени группы файла
└──────────── SUID (04000) — запуск от имени владельца файла
Пример: -rwsr-xr-x (вывод ls -l)
┌──────────────────────────────────────────────────────────────┐
│ - r w s r - x r - x │
│ │ └─┬─┘ └─┬─┘ └─┬─┘ │
│ │ u=rwx g=rx o=rx │
│ │ + SUID │
│ │ │
│ └── тип: - = обычный файл │
│ d = директория │
│ l = символическая ссылка │
│ b = блочное устройство │
│ c = символьное устройство │
└──────────────────────────────────────────────────────────────┘
Восьмеричное представление:
┌──────┬──────┬──────┬──────┐
│SUID/ │ user │group │other │
│SGID/ │ rwx │ rwx │ rwx │
│Sticky│ │ │ │
├──────┼──────┼──────┼──────┤
│ 4 │ 7 │ 5 │ 5 │ → 4755 = rwsr-xr-x
│ 1 │ 7 │ 7 │ 7 │ → 1777 = rwxrwxrwt (/tmp)
│ 0 │ 6 │ 4 │ 4 │ → 644 = rw-r--r--
└──────┴──────┴──────┴──────┘
Буква s (строчная) в позиции x означает, что и x, и SUID/SGID установлены. Буква S (заглавная) — SUID/SGID
установлен, но x нет. Аналогично t vs T для sticky.
Изменение прав: chmod¶
chmod принимает права в символьном или восьмеричном формате:
chmod u+x file.txt # добавить execute для владельца
chmod g-w file.txt # убрать write у группы
chmod u=rwx,g=rx,o= file.txt # явно задать права каждой категории
chmod 644 file.txt # восьмеричный формат
chmod -R 755 mydir/ # рекурсивно
Распространённые комбинации:
| Число | Символы | Назначение |
|---|---|---|
| 644 | rw-r--r-- | Обычный файл (читают все, пишет владелец) |
| 755 | rwxr-xr-x | Исполняемый файл или директория |
| 700 | rwx------ | Приватный файл, доступен только владельцу |
| 600 | rw------- | Приватный файл без права выполнения |
| 1777 | rwxrwxrwt | /tmp — все пишут, но удаляет только владелец |
Права на директории¶
Для директорий биты r, w, x имеют другой смысл:
| Бит | Для файла | Для директории |
|---|---|---|
| r | Читать содержимое | Просматривать список файлов (ls) |
| w | Изменять файл | Создавать и удалять файлы внутри |
| x | Выполнить | Входить в директорию (cd), обращаться к файлам |
Чтобы получить доступ к файлу по пути, нужен бит x на каждой родительской директории. Бит r без x позволяет
увидеть список имён, но не обратиться к самим файлам.
Изменение владельца и группы¶
chown alice file.txt # сменить владельца
chown alice:developers file.txt # сменить владельца и группу
chgrp developers file.txt # сменить только группу
chown -R alice mydir/ # рекурсивно
Ограничения: только root может менять владельца (chown). Владелец файла может менять его группу только на группу, в
которой сам состоит.
Системные вызовы chmod и chown¶
#include <sys/stat.h>
int chmod(const char *pathname, mode_t mode);
int fchmod(int fd, mode_t mode);
#include <unistd.h>
int chown(const char *pathname, uid_t owner, gid_t group);
int fchown(int fd, uid_t owner, gid_t group);
int lchown(const char *pathname, uid_t owner, gid_t group); // не разыменовывает симлинки
Передача -1 в качестве owner или group означает «не изменять»:
chown("file.txt", 1001, -1); // изменить только владельца
chown("file.txt", -1, 1002); // изменить только группу
Константы прав доступа:
#include <sys/stat.h>
S_IRUSR // 0400 — чтение для владельца
S_IWUSR // 0200 — запись для владельца
S_IXUSR // 0100 — выполнение для владельца
S_IRGRP // 0040 — чтение для группы
S_IWGRP // 0020 — запись для группы
S_IXGRP // 0010 — выполнение для группы
S_IROTH // 0004 — чтение для остальных
S_IWOTH // 0002 — запись для остальных
S_IXOTH // 0001 — выполнение для остальных
Специальные биты: SUID, SGID, Sticky¶
Помимо девяти обычных битов существуют три специальных:
| Бит | Восьмер. | Символ | На файле | На директории |
|---|---|---|---|---|
| SUID | 4xxx | s / S | Программа выполняется от имени владельца | (не применяется) |
| SGID | 2xxx | s / S | Программа выполняется от имени группы | Новые файлы наследуют группу каталога |
| Sticky | 1xxx | t / T | (нет эффекта) | Удалять файлы может только их владелец |
Строчная s или t означает, что соответствующий бит x тоже установлен; заглавная S или T — бит x не
установлен.
SUID — классический пример /usr/bin/passwd: он принадлежит root и имеет SUID, поэтому обычный пользователь может
менять свой пароль, хотя сам файл паролей доступен только root:
ls -l /usr/bin/passwd
# -rwsr-xr-x 1 root root ... /usr/bin/passwd
chmod u+s myprog # символьный формат
chmod 4755 myprog # восьмеричный формат
Sticky bit — /tmp доступен для записи всем, но удалить чужой файл нельзя:
SUID на скриптах не работает по соображениям безопасности — ядро игнорирует этот бит для интерпретируемых файлов.
Маска создания файлов: umask¶
При создании файла через open или mkdir запрошенные права маскируются через umask процесса:
Например, при umask 022 файл, созданный с mode=0666, получит права 0644, а директория с mode=0777 — 0755.
Просмотр текущей umask в shell:
Атрибуты файлов (ext2/ext4)¶
Атрибуты — это дополнительные флаги inode, поддерживаемые рядом файловых систем (ext2, ext3, ext4). Они влияют на поведение ФС независимо от прав доступа.
Просмотр и изменение:
lsattr file.txt # посмотреть атрибуты
chattr +i file.txt # установить атрибут
chattr -i file.txt # снять атрибут
chattr -R +A mydir/ # рекурсивно
Основные атрибуты:
| Символ | Название | Описание |
|---|---|---|
a |
append only | Файл можно только дополнять (не перезаписать, не усечь) |
i |
immutable | Файл неизменяем: нельзя изменить, удалить, переименовать |
A |
no atime update | Время доступа не обновляется (экономит I/O) |
s |
secure deletion | При удалении блоки затираются нулями |
S |
sync updates | Все изменения записываются на диск синхронно |
d |
no dump | Файл пропускается утилитой dump при резервном копировании |
Атрибут +i не может сломать даже root без предварительного chattr -i. Это полезно для защиты критических конфигов:
Программный доступ к атрибутам через ioctl:
#include <sys/ioctl.h>
#include <linux/fs.h>
#include <fcntl.h>
int fd = open("file.txt", O_RDONLY);
int attrs;
ioctl(fd, FS_IOC_GETFLAGS, &attrs);
attrs |= FS_IMMUTABLE_FL; // установить immutable
ioctl(fd, FS_IOC_SETFLAGS, &attrs);
close(fd);
Связанные темы¶
- Основы файловых систем — inode и поле
st_mode - Операции с директориями —
stat, макросыS_ISREG,S_ISDIR - Жёсткие и символические ссылки — права на симлинки и
lchown - Открытые файлы и процессы — UID/GID процесса и проверка прав
- Процессы: основы — UID, GID, effective UID процесса
Источники¶
man 2 chmod— системный вызов chmodman 2 chown— системный вызов chownman 2 umask— маска создания файловman 1 chmod— команда chmod в оболочкеman 1 chattr— управление атрибутами файлов ext2/ext4man 1 lsattr— просмотр атрибутов файловman 7 inode— поля inode, включая st_mode