Аргумент type имеет значение либо ACL_TYPE_ACCESS, для обновления ACL-списка доступа, либо ACL_TYPE_DEFAULT, для обновления ACL-списка по умолчанию для каталога.
Функция acl_from_text() переводит строку, содержащую длинную или краткую текстовую форму ACL-списка в ACL-список, расположенный в памяти, и возвращает описатель, который можно использовать для ссылки на данный список в последующих вызовах функции.
acl = acl_from_text(acl_string);
Функция acl_to_text() выполняет обратное преобразование, возвращая строку длинной текстовой формы для ACL-списка, на который указывает аргумент acl.
char *str;
ssize_t len;
str = acl_to_text(acl, &len);
Если аргумент len определен не как NULL, то буфер, на который он указывает, используется для возврата длины строки, являющейся результатом функции.
В следующих абзацах описаны некоторые широко используемые ACL-функции, не показанные на рис. 17.2.
Функция acl_calc_mask(&acl) вычисляет и задает права доступа в записи ACL_MASK для ACL-списка, расположенного в памяти, на описатель которого указывает аргумент функции. Как правило, эта функция применяется при создании или при изменении ACL-списка. Маска прав доступа ACL_MASK вычисляется благодаря объединению прав доступа из всех записей ACL_USER, ACL_GROUP и ACL_GROUP_OBJ. Полезным свойством данной функции является то, что она создает запись ACL_MASK, если она еще не существует. То есть если мы добавляем записи ACL_USER и ACL_GROUP в ACL-список, который ранее был минимальным, то затем мы можем воспользоваться данной функцией, гарантирующей создание записи ACL_MASK.
Функция acl_valid(acl) возвращает 0, если ACL-список, на который указывает ее аргумент, является допустимым, или –1 в обратном случае. ACL-список является допустимым, если истинны все приведенные ниже утверждения:
• каждая из записей ACL_USER_OBJ, ACL_GROUP_OBJ и ACL_OTHER встречается только один раз;
• если присутствует любая из записей ACL_USER или ACL_GROUP, то есть и запись ACL_MASK;
• присутствует не более одной записи ACL_MASK;
• каждая запись ACL_USER обладает уникальным идентификатором пользователя;
• каждая запись ACL_GROUP обладает уникальным идентификатором группы.
Функции acl_check() и acl_error() (последняя является расширением Linux) представляют собой альтернативные варианты функции acl_valid(), которые в меньшей степени портируемы, но обеспечивают более точное описание ошибки в случае некорректно сформированного ACL-списка. Подробности см. на страницах руководства.
Функция acl_delete_def_file(pathname) удаляет ACL-список по умолчанию для каталога, на который указывает аргумент pathname.
Функция acl_init(count) создает новую пустую ACL-структуру, изначально содержащую пространство по меньшей мере для ACL-записей, количество которых равно count. (Аргумент count является подсказкой для системы о предполагаемом использовании, это не жесткое ограничение.) Результатом функции является описатель для нового ACL-списка.
Функция acl_dup(acl) создает дубликат ACL-списка, на который указывает аргумент acl, и возвращает описатель для данного дубликата.
Функция acl_free(handle) высвобождает память, выделенную другими ACL-функциями. Так, например, необходимо применять эту функцию, чтобы высвободить память, которая была отведена в результате вызовов функций acl_from_text(), acl_to_text(), acl_get_file(), acl_init() и acl_dup().
В листинге 17.1 продемонстрировано использование некоторых библиотечных функций для работы с ACL-списками. Эта программа извлекает и выводит список для файла (то есть представляет часть возможностей команды getfacl). Если в командной строке указан параметр — d, программа выводит ACL-список по умолчанию (для каталога), а не ACL-список доступа.
Рассмотрим пример использования данной программы:
$ touch tfile
$ setfacl — m 'u: annie: r,u: paulh: rw,g: teach: r' tfile
$ ./acl_view tfile
user_obj rw-
user annie r–
user paulh rw-
group_obj r–
group teach r–
mask rw-
other r–
Исходный код к данной книге содержит также программу acl/acl_update.c, которая выполняет обновление ACL-списка (то есть представляет часть функций команды setfacl).
Листинг 17.1. Вывод ACL-списка доступа или списка по умолчанию для файла
acl/acl_view.c
#include
#include
#include "ugid_functions.h"
#include "tlpi_hdr.h"
static void
usageError(char *progName)
{
fprintf(stderr, "Usage: %s [-d] filename\n", progName);
exit(EXIT_FAILURE);
}
int
main(int argc, char *argv[])
{
acl_t acl;
acl_type_t type;
acl_entry_t entry;
acl_tag_t tag;
uid_t *uidp;
gid_t *gidp;
acl_permset_t permset;
char *name;
int entryId, permVal, opt;
type = ACL_TYPE_ACCESS;
while ((opt = getopt(argc, argv, "d"))!= -1) {
switch (opt) {