ИМЯ
request_key - запрашивает ключ из системы управления ключами ядраLIBRARY
Linux Key Management Utilities ( libkeyutils, -lkeyutils)СИНТАКСИС
#include <keyutils.h>
key_serial_t request_key(const char *type, const char *description, const char *_Nullable callout_info, key_serial_t dest_keyring);
ОПИСАНИЕ
Системный вызов request_key() пытается найти ключ заданного type с описанием (именем), совпадающим с description. Если ключ найти невозможно, то ключ может быть создан. Если ключ найден или создан, то request_key() присоединяет его к связке ключей, чей идентификатор указан keyring, и возвращает серийный номер ключа. Сначала request_key() выполняет рекурсивный поиск совпадающего ключа во всех связках ключей, присоединённых к вызвавшему процессу. Связки ключей просматриваются в следующем порядке: связки каждой нити, связки вызвавшего процесса и связки ключей сеанса. Если request_key() вызван из программы, вызванной request_key() от имени какого-то другого процесс для генерации ключа, то в дальнейшем будет осуществлён поиск по связкам ключей этого другого процесса, используя для определения доступа его идентификатор пользователя, группы и дополнительных групп и контекста безопасности. Поиск в дереве связок ключей выполняется сначала в ширину: искомые ключи в каждой связке проверяются на совпадение до рекурсивного перехода в дочерние связки ключей. Найдены могут быть только те ключи, которые разрешены вызывающему для поиска, и поиск может осуществляться только в разрешённых для поиска связках ключей. Если ключ не найден и callout равно NULL, то вызов завершается ошибкой ENOKEY. Если ключ не найден и callout не равно NULL, то ядро пытается вызвать пользовательскую программу для создания ключа. Подробности приведены ниже. Серийный номер dest_keyring может задаваться серийным номером допустимой связки ключей, на которую у вызывающего есть права на запись, или же это может быть один из следующих специальных идентификаторов связок ключей:- KEY_SPEC_THREAD_KEYRING
- Связка ключей вызывающей нити (смотрите thread-keyring(7)).
- KEY_SPEC_PROCESS_KEYRING
- Связка ключей вызывающего процесса (смотрите process-keyring(7)).
- KEY_SPEC_SESSION_KEYRING
- Связка ключей сеанса вызывающего (смотрите session-keyring(7)).
- KEY_SPEC_USER_KEYRING
- Связка ключей по UID вызывающего (смотрите user-keyring(7)).
- KEY_SPEC_USER_SESSION_KEYRING
- Связка ключей по UID сеанса вызывающего (смотрите user-session-keyring(7)).
- •
- Связка ключей запрашивающего ( KEY_REQKEY_DEFL_REQUESTOR_KEYRING, начиная с Linux 2.6.29).
- •
- Связка ключей нити ( KEY_REQKEY_DEFL_THREAD_KEYRING; смотрите thread-keyring(7)).
- •
- Связка ключей процесса ( KEY_REQKEY_DEFL_PROCESS_KEYRING; смотрите process-keyring(7)).
- •
- Связка ключей сеанса ( KEY_REQKEY_DEFL_SESSION_KEYRING; смотрите session-keyring(7)).
- •
- Связка ключей сеанса для идентификатора пользователя процесса ( KEY_REQKEY_DEFL_USER_SESSION_KEYRING; смотрите user-session-keyring(7)). Ожидается, что эта связка ключей всегда существует.
- •
- Связка ключей для идентификатора пользователя процесса ( KEY_REQKEY_DEFL_USER_KEYRING; смотрите user-keyring(7)). Ожидается, что эта связка ключей также всегда существует.
Запрос на создание ключа из пользовательского пространства
Если ядро не может найти ключ с соответствующим type и description, и callout не равно NULL, то ядро пытается вызвать программу из пользовательского пространства для создания ключа с заданными type и description. В этом случае выполняются следующие шаги:- (1)
- Ядро создаёт неинициализированный ключ U с запрошенными type и description.
- (2)
- Ядро создаёт ключ авторизации V, который ссылается на ключ U и сохраняются данные вызывающего request_key():
- (2.1)
- контекст, в котором ключ U должен быть создан и защищён и
- (2.2)
- контекст, из которого запросы связанного ключа могут быть проведены.
- Ключ авторизации создаётся со следующими свойствами:
- •
- Тип ключа — ".request_key_auth".
- •
- UID и GID ключа совпадают с ID в файловой системе для запрашивающего процесса.
- •
- Ключ даёт права на просмотр, чтение и поиск на ключ-владелец, а также право просмотра для ключа пользователя.
- •
- Описание (имя) ключа представляет собой Шестнадцатеричную строку идентификатора ключа, который будет создан в запрашивающей программе.
- •
- Полезные данные ключа берутся из данных callout_info.
- •
- Внутри ядра также сохраняется PID процесса, который был вызван request_key().
- (3)
- Ядро создаёт процесс, который запускает службу пользовательского пространства, такую как request-key(8), с новой связкой ключей сеанса с прицепленным ключом авторизации V.
- Данной программе передаются следующие аргументы командной строки:
- [0]
- Строка "/sbin/request-key".
- [1]
- Строка "create" (показывающая, что ключ будет создан).
- [2]
- Идентификатор ключа, который будет создан.
- [3]
- UID (в файловой системе) вызывающего request_key().
- [4]
- GID (в файловой системе) вызывающего request_key().
- [5]
- Идентификатор связки ключей нити вызывающего request_key(). Может быть ноль, если связка ключей не создана.
- [6]
- Идентификатор связки ключей процесса вызывающего request_key(). Может быть ноль, если связка ключей не создана.
- [7]
- Идентификатор связки ключей сеанса вызывающего request_key().
- Замечание: каждый аргумент командной строки, обозначающий идентификатор ключа, кодируется десятичным числом (в отличие от идентификаторов ключе, показанных в /proc/keys, которые выдаются в виде шестнадцатеричных значений).
- (4)
- Программа, порождённая на предыдущем шаге:
- •
- Принимает полномочия на создание ключа U с помощью keyctl(2) с операцией KEYCTL_ASSUME_AUTHORITY (обычно, с помощью функции keyctl_assume_authority(3)).
- •
- Получает исходящие данные (callout data) из полезной нагрузки ключа авторизации V (с помощью keyctl(2) с операцией KEYCTL_READ (или, чаще всего, с помощью функции keyctl_read(3)) с значением идентификатора ключа KEY_SPEC_REQKEY_AUTH_KEY.
- •
- Создаёт ключ (или выполняет другую программу, которая делает эту работу), с заданной полезной нагрузкой и связкой ключей назначения (связка ключей назначения та, которую запрашивающий указал при вызове request_key(), и которая быть доступна через специальный идентификатор ключа KEY_SPEC_REQUESTOR_KEYRING). Создание выполняется с помощью keyctl() с операцией KEYCTL_INSTANTIATE (или, чаще всего, с помощью функции keyctl_instantiate(3)). На этот момент вызов request_key() завершается и запрашивающая программа может продолжать выполнение.
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
On success, request_key() returns the serial number of the key it found or caused to be created. On error, -1 is returned and errno is set to indicate the error.ОШИБКИ
- EACCES
- Изменение связки ключей пользователю недоступно.
- EDQUOT
- Квота на ключи для данного пользователя была бы превышена, если бы этот ключ создался или был бы прицеплен в связку ключей.
- EFAULT
- Значение type, description или callout_info указывают вне доступного адресного пространства процесса.
- EINTR
- Запрос был прерван сигналом; смотрите signal(7).
- EINVAL
- Размер строки (включая конечный байт null), заданной в type или description, превышает ограничение (32 байта и 4096 байт, соответственно).
- EINVAL
- Размер строки (включая конечный байт null), заданной в callout_info, превышает размер системной страницы.
- EKEYEXPIRED
- Найден просроченный ключ, и замена не может быть получена.
- EKEYREJECTED
- Попытка генерации нового ключа была отвергнута.
- EKEYREVOKED
- Найден отозванный ключ, и замена не может быть получена.
- ENOKEY
- Искомый ключ не найден.
- ENOMEM
- Недостаточно памяти для создания ключа.
- EPERM
- The type argument started with a period ('.').
ВЕРСИИ
Данный системный вызов впервые появился в Linux 2.6.10. Возможность инициализации ключей по запросу была добавлена в Linux 2.6.13.СТАНДАРТЫ
Этот системный вызов является нестандартным расширением Linux.ПРИМЕРЫ
В программе, представленной ниже, показано использование request_key(). Аргументы type, description и callout_info для системного вызова берутся из значений, переданных в аргументах командной строки. В качестве связки ключей назначения вызов использует связку ключей сеанса. Чтобы показать работу программы сначала нужно создать подходящую запись в файле /etc/request-key.conf.$ sudo sh # echo 'create user mtk:* * /bin/keyctl instantiate %k %c %S' \ > /etc/request-key.conf # exit
Эта запись говорит о том, что когда должен быть создан новый ключ «user» с префиксом «mtk:», задача должна выполняться посредством команды keyctl(1) с операцией instantiate. Аргументы, передаваемые операции instantiate: идентификатор неинициализированного ключа ( %k); исходящие данные, переданные в вызов request_key() (%c); связка ключей сеанса ( %S) запрашивающего (т. е., вызывающий request_key()). Описание значений % смотрите в request-key.conf(5). Теперь запускаем программу и проверяем содержимое /proc/keys, чтобы удостовериться, что запрашиваемый ключ создан:
$ ./t_request_key user mtk:key1 "Payload data" $ grep '2dddaf50' /proc/keys 2dddaf50 I--Q--- 1 perm 3f010000 1000 1000 user mtk:key1: 12
Другой пример смотрите использования этой программы смотрите в keyctl(2).
Исходный код программы
/* t_request_key.c */ #include <keyutils.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { key_serial_t key; if (argc != 4) { fprintf(stderr, "Использование: %s тип описание callout-data\n", argv[0]); exit(EXIT_FAILURE); } key = request_key(argv[1], argv[2], argv[3], KEY_SPEC_SESSION_KEYRING); if (key == -1) { perror("request_key"); exit(EXIT_FAILURE); } printf("Key ID is %jx\n", (uintmax_t) key); exit(EXIT_SUCCESS); }
СМ. ТАКЖЕ
keyctl(1), add_key(2), keyctl(2), keyctl(3), capabilities(7), keyrings(7), keyutils(7), persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7), user-keyring(7), user-session-keyring(7), request-key(8) Файлы исходного кода ядра Documentation/security/keys/core.rst и Documentation/keys/request-key.rst (или, до Linux 4.13, файлы Documentation/security/keys.txt и Documentation/security/keys-request-key.txt).ПЕРЕВОД
Русский перевод этой страницы руководства был сделан aereiae <[email protected]>, Azamat Hackimov <[email protected]>, Dmitriy S. Seregin <[email protected]>, Katrin Kutepova <[email protected]>, Lockal <[email protected]>, Yuri Kozlov <[email protected]>, Баринов Владимир и Иван Павлов <[email protected]> Этот перевод является бесплатной документацией; прочитайте Стандартную общественную лицензию GNU версии 3 или более позднюю, чтобы узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ. Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте электронное письмо на [email protected]5 февраля 2023 г. | Linux man-pages 6.03 |