Работа с группами

**Права файлов**

Дать права на выполнение только владельцу:

`sudo chmod u+x myfile`

Дать права на выполнение владельцу и группе:

`sudo chmod ug+x myfile`

Можно комбинировать и права. Дать права на выполнение и запись владельцу и группе:

`sudo chmod ug+wx myfile`

Права можно не только давать, но и забирать. Убрать право на выполнение у всех (у пользователя, владельца, группы):

`sudo chmod -x myfile`

Убрать право на выполнение у остальных пользователей:

`sudo chmod o-x myfile`

Кроме + и - , есть ещё и присвоить =.

Разница в том, что +r и -r меняют только право на чтение. = меняет все три: rwx.

Если у файла права rwx r–x r– –, то

`sudo chmod +w myfile`

задаст права rwx rwx rw –.

А вот

`sudo chmod =w myfile`

задаст права –w– –w– –w –

Можно задать несколько вариантов прав:
`sudo chmod u=rwx,g=rx,o=r myfile`

**Восьмеричная система счисления позволяет предоставить права файлов в виде семи (восьми) цифр.**

Права 777 означают, что файл могут читать, изменять и исполнять все.

## Дополнительные атрибуты

К сожалению, трёх категорий прав не всегда оказывается достаточно.

Например, программа passwd, которая меняет пароль пользователя. Владельцем программы является root, а пароли хранятся в зашифрованном виде в /etc/shadow, владельцем которой тоже является root. И если пароль задаёт root, как его сменить пользователю? У программы passwd есть право на выполнение для остальных, поэтому пользователь user, запустив программу passwd, будет работать с UID=1001, и изменить файл /ect/shadows система не должна. Если это нужно сделать, есть особый атрибут SUID (Set User ID). Если этот атрибут присвоен исполняемому файлу (двоичному), при исполнении программы у неё будет UID не запустившего пользователя, а владельца файла. Технически это будет осуществляться через использование ещё двух идентификаторов. EUID (Equivalent UID) используется для определения прав доступа к файлу (он и будет установлен в 0), и RUID (Real UID) сохраняет настоящее значение UID (и будет равен 1001).

В листинге SUID выглядит так:

На месте права на исполнение для владельца вместо x показана буква s.

Установить SUID можно с помощью команды:

SUID — в определённой степени уязвимость. Так как обычно владельцем программы с атрибутом SUID является root, имеющий неограниченные права, при выполнении программа фактически выполняется от root и только она сама может контролировать корректность тех или иных действий (например, passwd, запущенная от простого пользователя не должна менять пароль суперпользователю и другим пользователям). Если в программе окажется уязвимость, теоретически пользователь-злоумышленник, не обладая нужными правами, сможет выполнить произвольный код. Например, если получится из программы с SUID запустить оболочку, она будет запущена с правами root.

По этой же причине SUID не работает для скриптов. Чтобы запустить скрипт с SUID, потребовалось бы присвоить SUID для интерпретатора оболочки или скрипта (ни в коем случае так никогда не делайте), либо скомпилировать в gcc простейшую обертку, которая запускает скрипт и присвоить ей SUID. Это будет работать, но не защищает от уязвимостей в самом скрипте.

Кроме SUID, существует аналогичный атрибут для групп — SGID (Set Group ID). Работает аналогично, но для исполняемого файла заменяет GID на GID группы файла. Фактически это тоже работает через механизмы RGID и EUID процессов.

Но, в отличии от SUID, у SGID есть ещё одна очень полезная особенность. Когда пользователь создаёт файл, файлу присваиваются UID и GID пользователя. Это не всегда удобно, особенно при совместном доступе. Но если для директории установить атрибут SGID, вновь создаваемый файл и директории в ней будут получать GID не пользователя, а родительской директории. Таким образом, если вы создадите директорию developer для совместной работы группы developer и установите соответствующую группу для данной директории, каждый разработчик, создавая файл, не будет вынужден менять группу на developer, она уже будет установлена. Останется только дать каждому файлу права на группу, а лучше сразу задать umask 002.

Установить SGID можно с помощью команды:

`sudo chmod g+s developer`

В листинге SGID выглядит так:

drwxrwsr-x 1 root developer 45420 февр. 17 06:42 /opt/developer

Третий атрибут — sticky bit. Он применяется для директорий, у которых права на чтение и выполнение даны для остальных пользователей, например, для директории /tmp.

При таких правах любой пользователь может не только создать или изменить файл (даже чужой), но и удалить. Но директория /tmp используется для межпроцессного взаимодействия, и такой вариант крайне нежелателен. Несколько программ могут обмениваться через файл, но удалить его должна только программа, создавшая его. Вот в таких случаях применяется атрибут sticky bit.

В листинге он отмечается буквой t в последней позиции:

drwxrwxrwt 17 root root 400 мая 23 17:50 /tmp/

Если файл или каталог не имеет атрибута execute для категории «остальные», буква t превращается в букву T. Этот атрибут для каталогов допускает удаление только файлов, принадлежащих пользователю.

Для файлов этот атрибут сейчас не используется. Во времена UNIX, когда диски были большими по размеру, но маленькими по объёму и невероятно медленными, этот атрибут использовался для исполняемых файлов, чтобы не выгружать образ программы из памяти после её завершения и ускорить повторный запуск программы.

Установить sticky bit можно с помощью команды:

Что интересно, дополнительные атрибуты можно задавать и в восьмеричной системе счисления.

Например:

`mkdir /developer/tmp`

`sudo chmod 1777 /developer/tmp`

В таком случае применяется уже не 3-значный, а 4-значный формат. Первый знак устанавливает расширенные атрибуты и рассчитывается как сумма для установленных расширенных битов: 1(sticky) + 2(SGID) + 4(SUID).

## Владелец и группа файла

Чтобы изменить группу, применяют утилиту chgrp. Сначала указываем группу, а потом файл(ы).

Например:

Или ещё лучше, укажем опцию -R и поменяем рекурсивно (для всех вложенных файлов тоже).

`sudo chgrp -R developer /var/www d`

Команда chown позволяет поменять владельца либо сразу владельца и группу:

или:

-R тоже работает (работает он и для chmod):

`chmod -R gu=rw,o=r,g+s /var/www`