KEYCTL(2)

ИМЯ
keyctl - работа с системой управления ключами ядра

ОБЗОР
#include <keyutils.h>

long keyctl(int cmd, ...)

/* для непосредственного вызова через syscall(2): */
#include <asm/unistd.h>
#include <linux/keyctl.h>
#include <unistd.h>

long syscall(__NR_keyctl, int option, __kernel_ulong_t arg2, __kernel_ulong_t arg3, __kernel_ulong_t arg4, __kernel_ulong_t arg5);

ОПИСАНИЕ
Вызов keyctl() (наряду с add_key(2)) позволяет управлять ключами пространства пользователя. Действие вызова keyctl() задаётся значением аргумента option, которое может быть одним из следующих:

KEYCTL_GET_KEYRING_ID
    Запрашивает связку ключей с идентификатором, задаваемом в arg2 (преобразуется в key_serial_t). Если значение arg3 не равно нулю, то создаётся новая связка ключей. Для нахождения вызывающий должен иметь права search для связок ключей. Аргументы arg4 и arg5 игнорируются.

KEYCTL_JOIN_SESSION_KEYRING
    Создаёт новую анонимную связку ключей сеанса (если arg2 равно NULL) или присоединяет существующую именованную связку ключей сеанса (arg2 должно указывать на строку с именем сеанса). Для присоединения вызывающий должен иметь права search для указанного имени связки ключей. Аргументы arg3, arg4 и arg5 игнорируются.

KEYCTL_UPDATE
    Изменяет данные ключа указанными данными. В аргументе arg2 (приводится к key_serial_t) должен указываться ID ключа, аргумент arg3 считается указателем на новые данные, а arg4 (приводится к size_t) должен содержать размер новых данных. Вызывающий должен иметь права write для указанного ключа и тип ключа должен поддерживать изменение. Этим вызовом может быть создан отрицательный ключ. Аргумент arg5 игнорируется.

KEYCTL_REVOKE
    Отзывает ключ с ID, указанном в arg2 (приводится к key_serial_t). Вызывающий должен иметь права write или setattr. Аргументы arg3, arg4, arg5 игнорируются.

KEYCTL_CHOWN
    Назначает владельца ключа. В аргументе arg2 (приводится к key_serial_t) содержится ID ключа, в аргументе arg3 (приводится к uid_t) содержится ID нового пользователя (или -1, если ID пользователя не нужно изменять), в аргументе arg4 (приводится к gid_t) содержится ID новой группы (или -1, если ID группы не нужно изменять). На ключ у вызывающего должны быть права setattr. Если изменяется UID или GID на группу, в которой вызывающий не является членом, вызывающий должен иметь мандат CAP_SYS_ADMIN (смотрите capabilities(7)). Если изменяется UID, то новый пользователь должен иметь достаточную квоту на приём ключа. Для перераспределения квоты со старого пользователя на нового должен быть изменён атрибут. Аргумент arg5 игнорируется.

KEYCTL_SETPERM
    Изменяет права на ключ с ID, указанном в аргументе arg2 (приводится к key_serial_t), на значение, указанное в аргументе arg3 (приводится к key_perms_t). У вызывающего на ключ должны быть права setattr. Если вызывающий не имеет мандата CAP_SYS_ADMIN, то он может изменять права только на свои ключи. Права содержат маску операций, доступных владельцу (начиная с Linux 2.6.14), пользователя, группу, другим. В каждой маске 8 бит, используется только 6. Доступные права:

    •   View. Позволяет читать атрибуты ключа. Требуется для KEYCTL_DESCRIBE.

    •   Read. Позволяет читать данные ключа. Требуется для KEYCTL_READ.

    •   Write. Позволяет изменять или добавлять данные ключа. Для связки ключей позволяет добавление и удаление ключей из связки. Требуется для KEYCTL_UPDATE, KEYCTL_REVOKE, KEYCTL_CLEAR, KEYCTL_LINK, KEYCTL_UNLINK.

    •   Search. Позволяет искать связки ключей и ключи. Поиск может быть рекурсивным только во вложенных связках, на которые есть права поиска. Требуется для KEYCTL_GET_KEYRING_ID, KEYCTL_JOIN_SESSION_KEYRING, KEYCTL_SEARCH KEYCTL_INVALIDATE.

    •   Link. Позволяет связывать ключ или связку ключей. Требуется для KEYCTL_LINK, KEYCTL_SESSION_TO_PARENT.

    •   Set attribute (начиная с Linux. 2.6.15). Позволяет изменять UID, GID и маску прав ключа. Требуется для KEYCTL_REVOKE, KEYCTL_CHOWN, KEYCTL_SETPERM.

    Аргументы arg4 и arg5 игнорируются.

KEYCTL_DESCRIBE
    Описывает ключ. Идентификатор описываемого ключа должен указываться в аргументе arg2 (приводится к key_serial_t), аргумент arg3 должен указывать на буфер назначения (тип char *), в аргументе arg4 должен указываться размер буфера (с ядерным типом size_t). У вызывающего на ключ должны быть права view. Запись в буфер выполняется только, если он задан как не NULL и в нём достаточно места для размещения описания. Само описание представляется в формате

        тип;uid;gid;права;описание<NUL>

    Аргумент arg5 игнорируется.

KEYCTL_CLEAR
    Стирает содержимое связки ключей с ID, указанном в аргументе arg2 (приводится к key_serial_t). Вызывающий должен иметь права write. Аргументы arg3, arg4, arg5 игнорируются.

KEYCTL_LINK
    Цепляет ключ (заданный в аргументе arg2 и приведённый к типу key_serial_t) в связку ключей (заданную в аргументе arg3 и приведённую к типу key_serial_t), если его нет такого же в связке, или заменяет связь для совпадающего ключа на новый ключ. Вызывающий должен иметь права link у добавляемого ключа и write в связке ключей, в которую добавляется ключ. Аргументы arg4 и arg5 игнорируются.

KEYCTL_UNLINK
    Отцепляет ключ (заданный в аргументе arg2 и приведённый к типу key_serial_t) от связки ключей (заданную в аргументе arg3 и приведённую к типу key_serial_t). Вызывающий должен иметь права write в связке ключей, из которой удаляется ключ. Если удаляется последняя ссылка на ключ, то этот ключ планируется к уничтожению. Аргументы arg4 и arg5 игнорируются.

KEYCTL_SEARCH
    Ищет ключ в связке ключей с ID, указанном в аргументе arg2 (приводится к типу key_serial_t). В аргументе arg3 должно быть значение типа char *, указывающее на имя типа искомого ключа (строка символов с NUL конце длиной до 32 байт), а в аргументе arg4 должно быть значение типа char *, указывающее на строку символов с NUL в конце (длиной до 4096 байт) с описанием искомого ключа. Поиск выполняется рекурсивно начиная со связки ключей с ID, указанном в arg2. Просматриваются только связки ключей, на которые у вызывающего есть права search (относится и к начальной связке ключей). Могут быть найдены только ключи на которые есть права search. Если аргумент arg5 (приводится к типу key_serial_t) содержит ненулевое значение, то оно рассматривается как ID связки ключей, к которой должен быть прицеплен найденный ключ.

KEYCTL_READ
    Читает данные ключа с ID, указанном в аргументе arg2 (приводится к типу key_serial_t), в буфер, на который указывает аргумент arg3 (приводится к типу char *), размером, указанным в аргументе arg4 (приводится к ядерному типу size_t). У вызывающего должны быть права read на ключ, или права search при поиске процесса связок ключей. Аргумент arg5 игнорируется.

KEYCTL_INSTANTIATE
    Создаёт (Instantiate) частично сконструированный ключ с ID, указанном в аргументе arg2 (приводится к типу key_serial_t) с данными, на который указывает аргумент arg3 (приводится к типу char *), размером, указанным в аргументе arg4 (приводится к ядерному типу size_t). Созданный ключ будет прицеплен к связке ключей с ID, который указан в аргументе arg5 (приводится к типу key_serial_t). Вызывающий должен иметь соответствующие права на создание (ключ авторизации).

KEYCTL_NEGATE
    Создаёт отрицательный частично сконструированный ключ с ID, указанном в аргументе arg2 (приводится к типу key_serial_t) с данными, задаёт срок действия (в секундах) из значения аргумента arg3 (приводится к типу unsigned int). Созданный ключ будет прицеплен к связке ключей с ID, указанном в аргументе arg4 (приводится к типу key_serial_t). Вызывающий должен иметь соответствующие права на создание (ключ авторизации, смотрите команду KEYCTL_ASSUME_AUTHORITY). Отрицательные ключи используются для ограничения повторяющихся вызовов request_key(), которые возвращают -ENOKEY, пока отрицательный ключ не будет просрочен. Эквивалентен вызову keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4). Аргумент arg5 игнорируется.

KEYCTL_SET_REQKEY_KEYRING (начиная с Linux 2.6.13)
    Прочитать или изменить связку ключей по умолчанию, в которой request_key() будет кэшировать ключи. В аргументе arg2 (приводится к типу int) должно быть одно из следующих значений, определённых в <linux/keyring.h>:
    #define KEY_REQKEY_DEFL_NO_CHANGE             -1 /* не изменять */
    #define KEY_REQKEY_DEFL_DEFAULT               0  /* связка по умолчанию */
    #define KEY_REQKEY_DEFL_THREAD_KEYRING        1  /* связка из нити */
    #define KEY_REQKEY_DEFL_PROCESS_KEYRING       2  /* связка из процесса */
    #define KEY_REQKEY_DEFL_SESSION_KEYRING       3  /* связка из сеанса */
    #define KEY_REQKEY_DEFL_USER_KEYRING          4  /* связка по UID */
    #define KEY_REQKEY_DEFL_USER_SESSION_KEYRING  5  /* связка сеанса с UID */
    #define KEY_REQKEY_DEFL_REQUESTOR_KEYRING     7  /* начиная с 2.6.29: связка запрашивающего */
    Все остальные значения (включая пока не поддерживаемое KEY_REQKEY_DEFL_GROUP_KEYRING) некорректны. Аргументы arg3, arg4 и arg5 игнорируются.

KEYCTL_SET_TIMEOUT (начиная с Linux 2.6.16)
    Задаёт срок действия. ID ключа указывается в аргументе arg2 (приводится к типу key_serial_t), срок действия (в секундах от текущего момента) задаётся в аргументе arg3 (приводится к типу unsigned int). Вызывающий должен иметь права setattr или авторизационный токен создания ключа. Срок действия 0 сбрасывает срок действия. Ключ и связи с ключом будут автоматически удалены после окончания срока действия. Аргументы arg4 и arg5 игнорируются.

KEYCTL_ASSUME_AUTHORITY (начиная с Linux 2.6.16)
    Наделяет (или отнимает) полномочиями создания ключа. ID ключа авторизации задаётся в аргументе arg2 (приводится к типу key_serial_t). Вызывающий должен иметь ключ создания в своих связках ключей процесса с правами search. Если ID, заданный в аргументе arg2, равен 0, то полномочия отбираются. Аргументы arg3, arg4 и arg5 игнорируются.

KEYCTL_GET_SECURITY (начиная с Linux 2.6.26)
    Возвращает метку безопасности LSM определённого ключа. ID ключа указывается в аргументе arg2 (приводится к типу key_serial_t). Буфер для сохранения метки безопасности указывается в аргументе arg3 (приводится к типу char *), а его размер задаётся в аргументе arg4 (приводится к ядерному типу size_t). Аргумент arg5 игнорируется.

KEYCTL_SESSION_TO_PARENT (начиная с Linux 2.6.32)
    Применяет связку ключей сеанса в родительском процессе.

    Пытается установить связку ключей сеансу вызывающего процесса в родительский процесс. Связка ключей должна существовать, вызывающий должен иметь права link, родительский процесс должен состоять из одной нити, иметь тех же эффективных владельцев как вызывающий процесс и не должен быть SUID/SGID.

    Связка ключей будет установлена в родителе, когда он возобновит работу в пользовательском пространстве. Аргументы arg2, arg3, arg4 и arg5 игнорируются.

KEYCTL_REJECT (начиная с Linux 2.6.39)
    Создаёт отрицательный частично сконструированный ключ с ID, указанном в аргументе arg2 (приводится к типу key_serial_t), задаёт срок действия (в секундах) из значения аргумента arg3 (приводится к типу unsigned int) и создаёт ошибку со значением из аргумента arg4 (приводится к типу unsigned int). Созданный ключ будет прицеплен к связке ключей с ID, указанном в аргументе arg5 (приводится к типу key_serial_t). Вызывающий должен иметь соответствующие права на создание (ключ авторизации, смотрите команду KEYCTL_ASSUME_AUTHORITY). Отрицательные ключи используются для ограничения повторяющихся вызовов request_key(), заставляя их возвращать указанную ошибку, пока отрицательный ключ не будет просрочен.

KEYCTL_INSTANTIATE_IOV (начиная с Linux 2.6.39)
    Создаёт ключ (с ID из аргумента arg2 с типом key_serial_t) с заданной (в аргументе arg3 с типом const struct iovec *) составными данными и цепляет ключ в заданную связку ключей (с ID из аргумента arg4 с типом key_serial_t), если указано ненулевое значение. Вызывающий должен иметь соответствующие права на создание (ключ авторизации, смотрите команду KEYCTL_ASSUME_AUTHORITY). Других прав не требуется. Аргумент arg5 игнорируется.

KEYCTL_INVALIDATE (начиная с Linux 3.5)
    Обнуляет срок действия ключа с ID из аргумента arg2 (приводится к типу key_serial_t). Вызывающий должен иметь права search. Ключи и его связи будут сразу автоматически вычищены. Аргументы arg3, arg4 и arg5 игнорируются.

KEYCTL_GET_PERSISTENT (начиная с Linux 3.13)
    Возвращает постоянную связку ключей пользователя, указанного в аргументе arg2 (приводится к типу uid_t) и цепляет её к связке ключей с ID из аргумента arg3 (приводится к типу key_serial_t). Если UID равно -1, то используется ID текущего пользователя. Аргументы arg4 и arg5 игнорируются.

KEYCTL_DH_COMPUTE (начиная с Linux 4.7)
    Вычисляет значение Диффи-Хеллмана. В аргументе arg2 содержится указатель на struct kayctl_dh_params, которая определена в <linux/keyctl.h> следующим образом:
    struct keyctl_dh_params {
        int32_t private;
        int32_t prime;
        int32_t base;
    };
    , где поля private, prime и base являются идентификаторами ключей, данные которых будут использованы для вычисления значений DH. Результат вычисляется как base^private mod prime. Аргумент arg3 (приводится к типу char *) должен быть указатель на буфер результата с размером, указанным в аргументе arg4 (приводится к ядерному типу size_t). Буфер должен быть достаточно большим чтобы вместить данные результата, в противном случае возвращается ошибка. Для получения размера в качестве буфера можно задать указатель NULL. Аргумент arg5 зарезервирован и должен быть равен 0.

На базе этих операций в libkeyutils созданы отдельные функции (перечислены в разделе СМОТРИТЕ ТАКЖЕ), что позволяет проверять типы с помощью компилятора.

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращаемое значение зависит от используемой команды:

KEYCTL_GET_KEYRING_ID
    Идентификатор запрашиваемой связки ключей.

KEYCTL_JOIN_SESSION_KEYRING
    Идентификатор присоединяемой связки ключей сеанса.

KEYCTL_DESCRIBE
    Размер описания (включая конечный байт NUL), безотносительно к указанному размеру буфера.

KEYCTL_SEARCH
    Найденный идентификатор ключа.

KEYCTL_READ
    Количество данных, доступных из ключа, безотносительно к указанному размеру буфера.

KEYCTL_SET_REQKEY_KEYRING
    Старые настройки (одна из KEY_REQKEY_DEFL_USER_*)

KEYCTL_ASSUME_AUTHORITY
    0, если задан ID, равный 0. ID ключа авторизации совпадает с ключом заданного ID, если указано ненулевое значение ID.

KEYCTL_GET_SECURITY
    Количество доступной информации (включая конечный байт NUL), безотносительно к указанному размеру буфера.

KEYCTL_GET_PERSISTENT
    Идентификатор постоянной связки ключей.

KEYCTL_DH_COMPUTE
    Количество копируемых байт.

Все остальные команды
    Ноль.

В случае ошибки возвращается -1, а errno устанавливается в значение ошибки.

ОШИБКИ

EACCES
    Операция с ключом не разрешена.

EDQUOT
    Квота на ключи для данного пользователя была бы превышена, если бы этот ключ создался или был бы прицеплен в связку ключей.

EKEYEXPIRED
    Найден или указан просроченный ключ.

EKEYREJECTED
    Найден или указан отклонённый (rejected) ключ.

EKEYREVOKED
    Найден или указан отозванный ключ.

ENOKEY
    Искомый ключ не найден или указан неверный ключ.

ENOTSUPP
    Значение option равно KEYCTL_UPDATE, а тип ключа не поддерживает обновление.

ENOTDIR
    Ожидается ключ с типом связки ключей, но указан ID ключа с другим типом.

ENFILE
    Связка ключей полна.

ENOENT
    Значение option равно KEYCTL_UNLINK, но запрашиваемый для отцепления ключ не прицеплен к связке ключей.

EINVAL
    Значение option равно KEYCTL_DH_COMPUTE, но указанный размер буфера мал для размещения результата. Укажите 0 в качестве размера буфера, чтобы получить минимальный размер требуемого буфера.

КОМПОНОВКА
Хотя это и системный вызов Linux, его нет в libc, но его можно найти в libkeyutils. При сборке программы компоновщику нужно указать параметр -lkeyutils.

СМОТРИТЕ ТАКЖЕ
keyctl(1), add_key(2), request_key(2), keyctl_chown(3), keyctl_clear(3), keyctl_describe(3), keyctl_describe_alloc(3), keyctl_get_keyring_ID(3), keyctl_instantiate(3), keyctl_join_session_keyring(3), keyctl_link(3), keyctl_negate(3), keyctl_read(3), keyctl_read_alloc(3), keyctl_revoke(3), keyctl_search(3), keyctl_set_reqkey_keyring(3), keyctl_set_timeout(3), keyctl_setperm(3), keyctl_unlink(3), keyctl_update(3), keyrings(7), request-key(8) Файл из дерева исходного кода ядра Documentation/security/keys.txt.