Provided by: manpages-ru-dev_4.21.0-2_all bug

ИМЯ

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

LIBRARY

       Standard C library (libc, -lc)

       Alternatively, Linux Key Management Utilities (libkeyutils, -lkeyutils); see NOTES.

СИНТАКСИС

       #include <linux/keyctl.h>     /* определения констант KEY* */
       #include <sys/syscall.h>      /* определения констант SYS_* */
       #include <unistd.h>

       long syscall(SYS_keyctl, int operation, unsigned long arg2,
                    unsigned long arg3, unsigned long arg4,
                    unsigned long arg5);

       Note: glibc provides no wrapper for keyctl(), necessitating the use of syscall(2).

ОПИСАНИЕ

       keyctl() позволяет программам пользовательского пространства выполнять операции с ключами.

       Операция,   выполняемая  keyctl(),  определяется  значением  аргумента  operation.  Каждая
       операция обёрнута  библиотекой  libkeyutils  (из  пакета  keyutils)  в  отдельную  функцию
       (описаны далее), чтобы компилятор мог выполнять проверку типов.

       Возможные значения operation:

       KEYCTL_GET_KEYRING_ID (начиная с Linux 2.6.10)
              Отобразить  идентификатор  специального  ключа  в идентификатор реального ключа для
              этого процесса.

              Эта операция ищет специальный ключ, чей идентификатор указан в arg2  (приводится  к
              key_serial_t).  Если  специальный  ключ найден, то функция возвращает идентификатор
              соответствующего реального ключа.  В  аргументе  arg2  могут  задаваться  следующие
              значения:

              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_SPEC_REQKEY_AUTH_KEY (начиная с Linux 2.6.16)
                     Ключ  авторизации,  созданный  request_key(2) и переданный процессу, который
                     был создан для генерации ключа. Этот  ключ  доступен  только  в  программах,
                     подобных request-key(8), которым передаётся ключ авторизации из ядра, и ключ
                     становится  недоступен  сразу  после  того,   как   запрошенный   ключ   был
                     инициализирован; смотрите request_key(2).

              KEY_SPEC_REQUESTOR_KEYRING (начиная с Linux 2.6.29)
                     Идентификатор  связки  ключей назначения у request_key(2). Эта связка ключей
                     доступна только в программах, подобных  request-key(8),  которым  передаётся
                     ключ авторизации из ядра, и ключ становится недоступен сразу после того, как
                     запрошенный ключ был инициализирован; смотрите request_key(2).

              The behavior if the key specified in arg2 does not exist depends on  the  value  of
              arg3 (cast to int).  If arg3 contains a nonzero value, then—if it is appropriate to
              do so (e.g., when looking up the user, user-session, or session key)—a new  key  is
              created  and  its  real  key  ID  returned  as the function result.  Otherwise, the
              operation fails with the error ENOKEY.

              Если в arg2 задан действительный идентификатор ключа  и  ключ  существует,  то  эта
              операция  просто  возвращает идентификатор ключа. Если ключ не существует, то вызов
              завершается ошибкой ENOKEY.

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

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

              Эта операция доступна в libkeyutils через функцию keyctl_get_keyring_ID(3).

       KEYCTL_JOIN_SESSION_KEYRING (начиная с Linux 2.6.10)
              Заменить связку ключей сеанса этого процесса новой связкой ключей сеанса.

              Если arg2 равно NULL, то создаётся анонимная связка ключей  с  описанием  «_ses»  и
              процесс  подписывается  на  эту  связку  ключей  как  на свою связку ключей сеанса,
              вытесняя предыдущую связку ключей сеанса.

              В противном случае, arg2 (приводится к char *) считается описанием (именем)  связки
              ключей и происходит следующее:

              •  Если  связка  ключей  с  таким  описанием существует, то процесс, если возможно,
                 попытается  подписаться  на  эту  связку  ключей  как  на  сеансовую;  если  это
                 невозможно,   то  возвращается  ошибка.  Чтобы  подписаться  на  связку  ключей,
                 вызывающий должен иметь право поиска в связке ключей.

              •  Если связка ключей с таким описанием не существует, то  создаётся  новая  связка
                 ключей с заданным описанием, и процесс подписывается на эту связку ключей как на
                 сеансовую.

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

              Эта операция доступна в libkeyutils через функцию keyctl_join_session_keyring(3).

       KEYCTL_UPDATE (начиная с Linux 2.6.10)
              Изменить полезные данные ключа.

              В аргументе arg2 (приводится к key_serial_t) указывается идентификатор  изменяемого
              ключа.  Аргумент arg3 (приводится к void *) указывает на новые полезные данные, а в
              аргументе arg4 (приводится к size_t) содержится  размер  новых  полезных  данных  в
              байтах.

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

              С помощью этой операции отрицательно  инициализированный  ключ  (смотрите  описание
              KEYCTL_REJECT) может быть положительно инициализирован.

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

              Эта операция доступна в libkeyutils через функцию keyctl_update(3).

       KEYCTL_REVOKE (начиная с Linux 2.6.10)
              Отозвать ключ с идентификатором из аргумента arg2 (приводится к key_serial_t). Ключ
              планируется к удалению сборщиком мусора; его больше нельзя найти, и  он  недоступен
              для  последующих операций. Дальнейшие попытки использования ключа будут приводить к
              ошибке EKEYREVOKED.

              Вызывающий должен иметь право записи и изменения атрибута в ключе.

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

              Эта операция доступна в libkeyutils через функцию keyctl_revoke(3).

       KEYCTL_CHOWN (начиная с Linux 2.6.10)
              Изменить владельца (идентификатор пользователя и группы) ключа.

              В аргументе arg2 (приводится к  key_serial_t)  содержится  идентификатор  ключа.  В
              аргументе  arg3  (приводится  к uid_t) содержится идентификатор нового пользователя
              (или -1, если идентификатор пользователя не меняется). В аргументе arg4 (приводится
              к  gid_t)  содержится идентификатор новой группы (или -1, если идентификатор группы
              не меняется).

              Ключ должен давать разрешение на изменения атрибута вызывающему.

              Для смены на новый UID или новый GID, если вызывающий  не  является  её  членом,  у
              вызывающего должен быть мандат CAP_SYS_ADMIN (смотрите capabilities(7)).

              Если  изменяется  UID,  то  у  нового пользователя должно быть достаточно квоты для
              принятия ключа. Уменьшение квоты будет  удалено  у  старого  пользователя,  который
              заменяется на идентификатор нового пользователя.

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

              Эта операция доступна в libkeyutils через функцию keyctl_chown(3).

       KEYCTL_SETPERM (начиная с Linux 2.6.10)
              Изменить   права   ключа   с   идентификатором  из  аргумента  arg2  (приводится  к
              key_serial_t) на права, указанные в аргументе arg3 (приводится к key_perm_t).

              Если вызывающий не имеет мандата CAP_SYS_ADMIN, то он может изменять права только у
              ключей,  которые  ему  принадлежат (точнее, UID файловой системы вызывающего должен
              совпадать с UID ключа).

              Ключ  должен  давать  разрешение  на  изменения  атрибута  независимо  от  мандатов
              вызывающего.

              Права   arg3  определяются  маской  доступных  операций  для  каждой  из  следующих
              пользовательских категорий:

              владение (начиная с Linux 2.6.14)
                     Это право предоставляется процессу,  который  владеет  ключом  (прицеплен  с
                     возможностью   поиска   к   одной   из  связок  ключей  процесса);  смотрите
                     keyrings(7).

              пользователь
                     Это право предоставляется процессу, чей UID файловой системы совпадает с UID
                     ключа.

              группа Это  право  предоставляется процессу, чей GID файловой системы или любой GID
                     из дополнительных групп совпадает с GID ключа.

              остальные
                     Это право предоставляется остальным процессам,  которые  не  относятся  к  к
                     категориям пользователь и группа.

              Категории пользователь, группа и остальные взаимоисключающие: если процесс попадает
              в категорию пользователь, то он не  получит  прав,  предоставленных  для  категории
              группа; если процесс попадает в категорию пользователь или группа, то он не получит
              прав, предоставляемых для категории остальные.

              Категория  владелец   предоставляет   права,   складываемые   из   прав   категории
              пользователь, группа или остальные.

              Каждая  маска  прав  имеет  размер  в  восемь  бит,  но  используются только шесть.
              Доступные права:

              просмотр
                     Позволяет читать атрибуты ключа.

                     Это право требуется для операции KEYCTL_DESCRIBE.

                     Биты прав для каждой категории KEY_POS_VIEW,  KEY_USR_VIEW,  KEY_GRP_VIEW  и
                     KEY_OTH_VIEW.

              чтение Позволяет читать полезные данные ключа.

                     Это право требуется для операции KEYCTL_READ.

                     Биты  прав  для  каждой категории KEY_POS_READ, KEY_USR_READ, KEY_GRP_READ и
                     KEY_OTH_READ.

              запись Позволяет изменять или добавлять полезные данные ключа.  Для  связки  ключей
                     позволяет добавление и удаление ключей из связки.

                     Это право требуется для операций KEYCTL_UPDATE, KEYCTL_REVOKE, KEYCTL_CLEAR,
                     KEYCTL_LINK и KEYCTL_UNLINK.

                     Биты прав для каждой категории KEY_POS_WRITE, KEY_USR_WRITE, KEY_GRP_WRITE и
                     KEY_OTH_WRITE.

              поиск  Позволяет  искать связки ключей и ключи. Поиск может быть рекурсивным только
                     во вложенных связках, на которые есть право поиска.

                     Это     право     требуется     для     операций      KEYCTL_GET_KEYRING_ID,
                     KEYCTL_JOIN_SESSION_KEYRING, KEYCTL_SEARCH и KEYCTL_INVALIDATE.

                     Биты    прав    для   каждой   категории   KEY_POS_SEARCH,   KEY_USR_SEARCH,
                     KEY_GRP_SEARCH и KEY_OTH_SEARCH.

              связь  Позволяет прицеплять ключ или связку ключей.

                     Это право требуется для операций KEYCTL_LINK и KEYCTL_SESSION_TO_PARENT.

                     Биты прав для каждой категории KEY_POS_LINK,  KEY_USR_LINK,  KEY_GRP_LINK  и
                     KEY_OTH_LINK.

              setattr (начиная с Linux 2.6.15).
                     Позволяет изменять UID, GID и маску прав ключа.

                     Это   право   требуется   для   операций   KEYCTL_REVOKE,   KEYCTL_CHOWN   и
                     KEYCTL_SETPERM.

                     Биты   прав   для   каждой   категории   KEY_POS_SETATTR,   KEY_USR_SETATTR,
                     KEY_GRP_SETATTR и KEY_OTH_SETATTR.

              Для  удобства,  следующие  макросы  определены  как  маски всех бит прав для каждой
              пользовательской категории: KEY_POS_ALL, KEY_USR_ALL KEY_GRP_ALL и KEY_OTH_ALL.

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

              Эта операция доступна в libkeyutils через функцию keyctl_setperm(3).

       KEYCTL_DESCRIBE (начиная с Linux 2.6.10)
              Получить строку, описывающую атрибуты указанного ключа.

              Описываемый идентификатор  ключа  задаётся  в  arg2  (приводится  к  key_serial_t).
              Описывающая  строка  возвращается в буфере, на который указывает arg3 (приводится к
              char *); в arg4 (приводится к size_t) задаётся размер этого буфера в байтах.

              Ключ должен давать вызывающему разрешение на просмотр.

              Возвращаемая строка оканчивается null и содержит следующую информацию о ключе:

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

              Здесь тип и описание являются строками, uid  и  gid  —  десятичным  числом  в  виде
              строки,  а права — шестнадцатеричной маской прав. Описывающая строка записывается в
              следующем формате:

                  %s;%d;%d;%08x;%s

              Замечание: описывающая строка представлена  в  таком  виде,  чтобы  её  можно  было
              расширить  в  будущих  версиях  ядра. В частности, поле описание не будет содержать
              точек с запятой; его нужно отделять проходя с конца строки в поиске последней точки
              с запятой. Это позволяет вставить в будущих версиях новые поля.

              Запись  в  буфер  производится  только  если  arg3 не равно NULL и указанный размер
              буфера достаточен для  описывающей  строки  (включая  конечный  байт  null).  Чтобы
              понять, что буфер был мал, проверьте, что возвращаемое значение больше arg4.

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

              Эта операция доступна в libkeyutils через функцию keyctl_describe(3).

       KEYCTL_CLEAR
              Стереть содержимое связки ключей (т. е., удалить из неё все ключи).

              Идентификатор  ключа (должен иметь тип связки ключей) задаётся в arg2 (приводится к
              key_serial_t).

              Вызывающий должен иметь право записи в связку ключей.

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

              Эта операция доступна в libkeyutils через функцию keyctl_clear(3).

       KEYCTL_LINK (начиная с Linux 2.6.10)
              Прицепить ключ к связке ключей.

              Прицепляемый ключ указывается в arg2 (приводится  к  key_serial_t);  связка  ключей
              указывается в arg3 (приводится к key_serial_t).

              Если  ключ  с  тем же типом и описанием уже прицеплен к связке ключей, то этот ключ
              отцепляется от связки ключей.

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

              Вызывающий  должен иметь право зацепки (link) у добавляемого ключа и право записи у
              связки ключей.

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

              Эта операция доступна в libkeyutils через функцию keyctl_link(3).

       KEYCTL_UNLINK (начиная с Linux 2.6.10)
              Отцепить ключ от связки ключей.

              Идентификатор отцепляемого ключа указывается в arg2  (приводится  к  key_serial_t);
              идентификатор  связки  ключей,  от  которой  отцепляется  ключ,  указывается в arg3
              (приводится к key_serial_t).

              Если ключ не прицеплен к связке ключей, то возвращается ошибка.

              Вызывающий должен иметь право записи в связку ключей, из которой удаляется ключ.

              Если удаляется последняя ссылка на ключ, то этот ключ планируется к уничтожению.

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

              Эта операция доступна в libkeyutils через функцию keyctl_unlink(3).

       KEYCTL_SEARCH (начиная с Linux 2.6.10)
              Найти ключ в дереве связок ключей, вернуть его идентификатор и, при  необходимости,
              прицепить его к заданной связке ключей.

              Идентификатор  начала  дерева ключей, в котором производится поиск, задаётся в arg2
              (приводится к key_serial_t). Поиск выполняется сначала вширь и рекурсивно.

              В аргументах arg3 и arg4 задаётся искомый  ключ:  в  arg3  (приводится  к  char  *)
              содержится  тип  ключа  (строка символов длиной до 32 байт с учётом конечного байта
              null), а в arg4 (приводится к char *) содержится описание ключа (строка символов до
              4096 байт с учётом конечного байта null).

              Связка ключей источник должна представлять право поиска вызывающему. При выполнении
              рекурсивного поиска будут  просматриваться  только  связки  ключей,  представляющие
              право поиска вызывающему. Могут быть найдены только ключи, на которые у вызывающего
              есть право поиска.

              Если ключ найден, то его идентификатор возвращается как результат функции.

              Если ключ найден и значение arg5 (приводится к key_serial_t) не равно  нулю,  то  с
              теми  же  ограничениями  и  правилами  как у KEYCTL_LINK ключ прицепляется в связку
              ключей, идентификатор  которой  указан  в  arg5.  Если  связка  ключей  назначения,
              указанная  в  arg5,  уже  содержит ключ того же типа и с тем же описанием, то связь
              будет замещена новой с ключом, найденным этой операцией.

              Вместо корректных существующих идентификаторов связок  ключей  источника  (arg2)  и
              приёмника   (arg5)   можно  указывать  специальные  идентификаторы  связок  ключей,
              описанных в KEYCTL_GET_KEYRING_ID.

              Эта операция доступна в libkeyutils через функцию keyctl_search(3).

       KEYCTL_READ (начиная с Linux 2.6.10)
              Прочитать полезные данные ключа.

              Идентификатор  ключа,  из  которого  читаются  полезные  данные,  задаётся  в  arg2
              (приводится  к  key_serial_t). Это может быть идентификатор существующего ключа или
              любой специальный идентификатор ключа, описанный в KEYCTL_GET_KEYRING_ID.

              Полезные данные помещаются в буфер,  указываемый  в  arg3  (приводится  к  char *);
              размер буфера должен быть указан в arg4 (приводится к size_t).

              Возвращаемые  данные  будут  обработаны  для  представления  согласно  типу  ключа.
              Например,  связка  ключей  будет  возвращена  как  массив  элементов  key_serial_t,
              представляющих  идентификаторы  всех  ключей  связки. Данные типа ключа user  будут
              возвращены как есть. Если для типа ключа эта функция не  реализована,  то  операция
              завершается ошибкой EOPNOTSUPP.

              Если  arg3 не равно NULL, то копируется столько полезных данных сколько вмещается в
              буфер. При успешном выполнении возвращаемое значение всегда равно  полному  размеру
              полезных   данных.   Чтобы  удостовериться  что  буфер  был  достаточного  размера,
              убедитесь, что возвращаемое значение меньше или равно значению, указанному в arg4.

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

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

              Эта операция доступна в libkeyutils через функцию keyctl_read(3).

       KEYCTL_INSTANTIATE (начиная с Linux 2.6.10)
              Положительно   инициализировать   неинициализированный   ключ  заданными  полезными
              данными.

              Идентификатор   инициализированного   ключа   задаётся   в   arg2   (приводится   к
              key_serial_t).

              Полезные  данные  ключа  задаются в буфере, указанном в arg3 (приводится к void *);
              размер буфера задаётся в arg4 (приводится к size_t).

              Ссылка на полезные данные может быть равна NULL и размер буфера может равняться  0,
              если это поддерживается типом ключа (например, если это связка ключей).

              Операция  может  завершиться  с ошибкой, если полезные данные заданы в неправильном
              формате или содержат ошибки.

              Если arg5 (приводится к key_serial_t) не равно нулю, то с теми же  ограничениями  и
              правилами  как  у KEYCTL_LINK инициализированный ключ прицепляется в связку ключей,
              идентификатор которой указан в arg5.

              Вызывающий должен иметь соответствующий  ключ  авторизации  и  после  инициализации
              ключа  ключ  авторизации  отзывается. Иначе говоря, эта операция доступна только из
              программ,   подобных   request-key(8).   В   request_key(2)    смотрите    описание
              неинициализированных ключей и их инициализацию.

              Эта операция доступна в libkeyutils через функцию keyctl_instantiate(3).

       KEYCTL_NEGATE (начиная с Linux 2.6.10)
              Отрицательно инициализировать неинициализированный ключ.

              Данная операция эквивалентен вызову:

                  keyctl(KEYCTL_REJECT, arg2, arg3, ENOKEY, arg4);

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

              Эта операция доступна в libkeyutils через функцию keyctl_negate(3).

       KEYCTL_SET_REQKEY_KEYRING (начиная с Linux 2.6.13)
              Задать  связку  ключей по умолчанию, в которую будут цепляться неявно запрашиваемые
              ключи для этой нити, и вернуть предыдущее значение. Неявные запросы ключа  делаются
              внутренними  компонентами  ядра,  такое  может  происходить, например, при открытии
              файлов в файловой системе AFS или NFS. Задание связки  ключей  по  умолчанию  также
              учитывается  при  запросе  ключа  из  пользовательского  пространства;  подробности
              смотрите в request_key(2).

              В аргументе arg2 (приводится к int) должно содержаться одно из следующих  значений,
              задающих новую связку ключей по умолчанию:

              KEY_REQKEY_DEFL_NO_CHANGE
                     Не изменять связку ключей по умолчанию. Используется для определения текущей
                     связки ключей по умолчанию (без её изменения).

              KEY_REQKEY_DEFL_DEFAULT
                     Применить  действие  по  умолчанию,  то  есть  использовать  связку  ключей,
                     привязанную  к  нити,  если есть, в противном случае привязанную к процессу,
                     если есть, иначе привязанную к сеансу, если есть, иначе привязанную к сеансу
                     UID, иначе привязанную к пользователю.

              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_KEYRING
                     В качестве новой связки ключей по умолчанию использовать связку  ключей  UID
                     (user-keyring(7)).

              KEY_REQKEY_DEFL_USER_SESSION_KEYRING
                     В  качестве  новой связки ключей по умолчанию использовать связку ключей UID
                     сеанса (user-session-keyring(7)).

              KEY_REQKEY_DEFL_REQUESTOR_KEYRING (начиная с Linux 2.6.29)
                     Использовать связку ключей запрашивающего.

              Любые другие значения недопустимы.

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

              Параметр, контролируемый данной  операцией,  наследуется  потомком  при  fork(2)  и
              сохраняется при execve(2).

              Эта операция доступна в libkeyutils через функцию keyctl_set_reqkey_keyring(3).

       KEYCTL_SET_TIMEOUT (начиная с Linux 2.6.16)
              Назначить время ожидания ключа.

              Идентификатор  ключа  задаётся в arg2 (приводится к key_serial_t). Время ожидания в
              секундах отсчитывается от текущего времени и задаётся в arg3 (приводится к unsigned
              int). Время ожидания изменяется по часам реального времени.

              Значение времени ожидания 0 очищается существующее ожидание ключа.

              В файле /proc/keys показывается оставшееся время до момента просрочки каждого ключа
              (это единственной способ узнать время ожидания ключа).

              Вызывающий должен иметь право  изменения  атрибута  в  ключе  или  быть  держателем
              авторизационного токена инициализации ключа (смотрите request_key(2)).

              Ключ  и  все  ссылки  на  него  будут  автоматически удалены сборщиком мусора после
              истечения времени ожидания. Последующие попытки доступа к ключу  будут  завершаться
              ошибкой EKEYEXPIRED.

              Данную   операцию   невозможно   применить   для   задания   ожидания  отозванного,
              просроченного или отрицательно инициализированного ключа.

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

              Эта операция доступна в libkeyutils через функцию keyctl_set_timeout(3).

       KEYCTL_ASSUME_AUTHORITY (начиная с Linux 2.6.16)
              Выдать (или отозвать) право вызывающей нити на инициализацию ключа.

              В аргументе arg2 (приводится к key_serial_t)  указывается  ненулевое  идентификатор
              ключа для выдачи права допуска или 0 для отмены права допуска.

              Если  arg2 не равно нулю, то будет выдано право допуска к указанному идентификатору
              неинициализированного ключа. Далее этот ключ может быть инициализирован посредством
              операций     KEYCTL_INSTANTIATE,    KEYCTL_INSTANTIATE_IOV,    KEYCTL_REJECT    или
              KEYCTL_NEGATE. После инициализации ключа, у  нити  автоматически  отменяется  право
              доступа для инициализации ключа.

              Право  доступа  на  ключ  может быть выдано только, если вызывающая нить содержит в
              своих связках ключей ключ авторизации, который связан  с  указанным  ключом  (иначе
              говоря,  операция  KEYCTL_ASSUME_AUTHORITY  доступна  только  из программ, подобных
              request-key(8); в request_key(2) смотрите описание как используется эта  операция).
              Вызывающий должен иметь право поиска ключа авторизации.

              Если  указанный  ключ совпадает с ключом авторизации, то возвращается идентификатор
              этого ключа. Ключ авторизации можно прочитать (KEYCTL_READ) для получения исходящей
              информации, переданной в request_key(2).

              Если  идентификатор  в  arg2  равен  0, то имеющееся в настоящее время право выдачи
              очищается (отменяется и возвращается 0.

              Механизм KEYCTL_ASSUME_AUTHORITY  позволяет  программе,  такой  как  request-key(8)
              выдать  необходимые  права  для  инициализации  нового неинициализированного ключа,
              который был создан предшествующим вызовом request_key(2). Дополнительную информацию
              смотрите     в     request_key(2)     и     в    файле    исходного    кода    ядра
              Documentation/security/keys-request-key.txt.

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

              Эта операция доступна в libkeyutils через функцию keyctl_assume_authority(3).

       KEYCTL_GET_SECURITY (начиная с Linux 2.6.26)
              Получить метку безопасности LSM (модуль безопасности Linux) указанного ключа.

              В  arg2  (приводится  к  key_serial_t)  задаётся  идентификатор  ключа,  чью  метку
              безопасности  нужно  получить.  Метка  безопасности (завершается байтом null) будет
              помещена в буфер, указанный в аргументе arg3 (приводится к char *);  размер  буфера
              должен быть указан в arg4 (приводится к size_t).

              Если  arg3  равно  NULL  или  размер  буфера,  указанный в arg4, мал, то в качестве
              результата функции возвращается полный размер строки  метки  безопасности  (включая
              конечный байт null) и в буфер ничего не копируется.

              Вызывающий должен иметь право просмотра указанного ключа.

              Возвращаемая  строка метки безопасности имеет формат, определяемый в соответствии с
              действующим LSM. Например, при используемом SELinux она может выглядеть так:

                  unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

              Если в данный момент LSM не работает, то в буфер помещается пустая строка.

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

              Эта  операция  доступна  в  libkeyutils  через  функции  keyctl_get_security(3)   и
              keyctl_get_security_alloc(3).

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

              Связка ключей родительского процесса будет заменена в  момент  следующего  перехода
              родителя из пространства ядра в пространство пользователя.

              Связка  ключей  должна  существовать  и  позволять  вызывающему  выполнять  сцепку.
              Родительский процесс должен быть с одной нитью и иметь те же действующие права  как
              этот  процесс  и  не  быть  set-user-ID  или set-group-ID. UID связки ключей сеанса
              родительского процесса (если есть), а также UID связки  ключей  сеанса  вызывающего
              должны совпадать с действующим UID вызывающего.

              Факт  того, что эта операция затрагивает родительский процесс, позволяет программе,
              такой как оболочка, запускать дочерний процесс, который  с  помощью  этой  операции
              изменит  связку  ключей  сеанса  оболочки  (это  то, что делает команда new_session
              keyctl(1)).

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

              Эта операция доступна в libkeyutils через функцию keyctl_session_to_parent(3).

       KEYCTL_REJECT (начиная с Linux 2.6.39)
              Пометить ключ как отрицательно инициализированный и задать таймер  действия  ключа.
              Эта  операция  предоставляет собой надмножество возможности операции KEYCTL_NEGATE,
              представленной ранее.

              Идентификатор отрицательно инициализируемого ключа указывается в arg2 (приводится к
              key_serial_t).  В  arg3  (приводится к unsigned int) указывается срок жизни ключа в
              секундах. В arg4 (приводится к unsigned int) указывается ошибка,  возвращаемая  при
              нахождении этого ключа — обычно равно EKEYREJECTED, EKEYREVOKED или EKEYEXPIRED.

              Если  arg5  (приводится к key_serial_t) не равно нулю, то с теми же ограничениями и
              правилами как у KEYCTL_LINK отрицательно  инициализированный  ключ  прицепляется  в
              связку ключей, идентификатор которой указан в arg5.

              Вызывающий  должен  иметь  соответствующий  ключ  авторизации.  Иначе  говоря,  эта
              операция  доступна  только   из   программ,   подобных   request-key(8).   Смотрите
              request_key(2).

              Вызывающий  должен  иметь  соответствующий  ключ  авторизации и после инициализации
              ключа ключ авторизации отзывается. Иначе говоря, эта операция  доступна  только  из
              программ,    подобных    request-key(8).   В   request_key(2)   смотрите   описание
              неинициализированных ключей и их инициализацию.

              Эта операция доступна в libkeyutils через функцию keyctl_reject(3).

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

              This operation is the same as KEYCTL_INSTANTIATE, but the payload data is specified
              as an array of iovec structures (see iovec(3type)).

              Указатель на вектор полезных данных передаётся в arg3 (приводится  к  const  struct
              iovec  *).  Количество  элементов  в векторе задаётся в arg4 (приводится к unsigned
              int).

              Значение аргумента arg2 (идентификатор ключа) и arg5 (идентификатор связки  ключей)
              рассматриваются также как у KEYCTL_INSTANTIATE.

              Эта операция доступна в libkeyutils через функцию keyctl_instantiate_iov(3).

       KEYCTL_INVALIDATE (начиная с Linux 3.5)
              Пометить ключ как недействительный.

              Идентификатор  ключа,  отмечаемого  недействительным, задаётся в arg2 (приводится к
              key_serial_t).

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

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

              Ключи, помеченный как недействительные, сразу  становятся  невидимыми  для  обычных
              операций   с  ключами,  хотя  их  видно  в  /proc/keys  (отмечены  флагом  «i»)  до
              действительного удаления.

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

              Эта операция доступна в libkeyutils через функцию keyctl_invalidate(3).

       KEYCTL_GET_PERSISTENT (начиная с Linux 3.13)
              Получить постоянную связку ключей (persistent-keyring(7)) заданного пользователя  и
              прицепить её к указанную связку ключей.

              Идентификатор  пользователя  указывается  в arg2 (приводится к uid_t). Если указано
              значение -1,  то  используется  реальный  идентификатор  пользователя  вызывающего.
              Идентификатор   связки   ключей   назначения   указывается  в  arg3  (приводится  к
              key_serial_t).

              Вызывающий должен иметь мандат CAP_SETUID в своём  пространстве  имён  пользователя
              чтобы получить постоянную связку ключей для идентификатора пользователя, который не
              совпадает с реальным или действующим идентификатора пользователя вызывающего.

              При успешном выполнении вызова добавляет  ссылка  на  постоянную  связку  ключей  в
              связку ключей с идентификатором, указанном arg3.

              Вызывающий должен иметь право записи в связку ключей.

              Если постоянная связка ключей не существует, то она будет создана ядром.

              Каждый  раз  при выполнении операции KEYCTL_GET_PERSISTENT срок действия постоянной
              связки ключей сбрасывается в значение:

                  /proc/sys/kernel/keys/persistent_keyring_expiry

              По истечению срока действия постоянная связка ключей удаляется и все ссылки на  неё
              затем удаляются сборщиком мусора.

              Persistent keyrings were added in Linux 3.13.

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

              Эта операция доступна в libkeyutils через функцию keyctl_get_persistent(3).

       KEYCTL_DH_COMPUTE (начиная с Linux 4.7)
              Вычислить  открытый  и закрытый ключ Диффи-Хеллмана, возможно применяя к результату
              функцию формирования ключа (key derivation function, KDF).

              В аргументе arg2 передаётся указатель  на  набор  параметров,  содержащих  серийные
              номера  трёх ключей "user", используемых в вычислении Диффи-Хеллмана, упакованных в
              следующую структуру:

                  struct keyctl_dh_params {
                      int32_t private; /* локальный закрытый ключ */
                      int32_t prime; /* основание, известное обеим сторонам */
                      int32_t base;  /* базовое целое: из общего генератора
                                        или из открытого ключа удалённой стороны */
                  };

              Для каждого из трёх указанных в структуре ключей у вызывающего должно быть право на
              чтение.   Полезные  данные  этих  ключей  используются  для  вычисления  результата
              Диффи-Хеллмана по формуле:

                  base ^ private mod prime

              Если база это общий генератор, то результатом будет локальный открытый  ключ.  Если
              база это открытый ключ удалённой стороны, то результатом будет общий закрытый ключ.

              Аргумент  arg3  (приводится  к  char  *)  указывает  на буфер, в который помещается
              результат вычисления. Размер буфера задаётся в arg4 (приводится к size_t).

              Буфер должен быть достаточного размера для хранения выходных  данных,  в  противном
              случае возвращается ошибка. Если значение arg4 равно нулю, то буфер не используется
              и операция возвращает минимально требуемый размер буфера (т. е., длину основания).

              Вычисления Диффи-Хеллмана можно выполнять в пространстве пользователя, но требуется
              библиотека  целых  чисел  многократной  точности (MPI). Помещение реализации в ядро
              даёт доступ к реализации MPI ядра и позволяет использовать аппаратуру шифрования  и
              ускорения.

              Добавление  поддержки  вычисления  DH  в системный вызов keyctl() считается хорошим
              решением, так как алгоритм DH используется для получения общих  ключей;  также  для
              типа ключа можно задать подходящую реализацию DH (программную или аппаратную).

              Если аргумент arg5 равен NULL, то возвращается сам результат DH. В противном случае
              (начиная с Linux 4.12), значение равно указателю на структуру, в  которой  задаются
              параметры для применения в операции KDF:

                  struct keyctl_kdf_params {
                      char *hashname;     /* имя алгоритма хэширования */
                      char *otherinfo;    /* SP800-56A OtherInfo */
                      __u32 otherinfolen; /* размер данных otherinfo */
                      __u32 __spare[8];   /* зарезервировано */
                  };

              В  поле  hashname  содержится строка, завершающаяся null, которой задаётся имя хэша
              (доступно в программном интерфейсе шифрования ядра; список хэшей сложно описать;  в
              файле  «Kernel  Crypto  API  Architecture»  ⟨https://www.kernel.org/doc/html/latest
              /crypto/architecture.html⟩ можно найти как компонуются имена  хэшей  из  алгоритмов
              шифрования  и  шаблонов с типом CRYPTO_ALG_TYPE_SHASH с учётом доступного исходного
              кода ядра и настроек) для применения к результату DH в операции KDF.

              Поле otherinfo содержит данные OtherInfo, описанные в  SP800-56A,  раздел  5.8.1.2,
              зависящие  от  алгоритма.  Эти  данные  объединяются  с  результатом  операции DH и
              предоставляются  как  входные  операции  KDF.  Его  размер   указывается   в   поле
              otherinfolen  и ограничивается константой KEYCTL_KDF_MAX_OI_LEN, которая определена
              в security/keys/internal.h и равна 64.

              Поле __spare в настоящее время не используется. Оно игнорировалось  до  Linux  4.13
              (но  всё  равно  доступно  из  пользовательского пространства, так как копируется в
              ядро), и, начиная с Linux 4.13, должно содержать нули.

              Реализация KDF соответствует SP800-56A, а также SP800-108 (счётчик KDF).

              This operation is exposed by libkeyutils (from libkeyutils 1.5.10 onwards) via  the
              functions keyctl_dh_compute(3)  and keyctl_dh_compute_alloc(3).

       KEYCTL_RESTRICT_KEYRING (начиная с Linux 4.12)
              Применить ограничение прицепить ключ к связке ключей с идентификатором, указанном в
              arg2 (приводится к типу key_serial_t). Вызывающий должен  иметь  право  setattr  на
              ключ.  Если  arg3  равно  NULL,  то  все  попытки  добавить  ключ  в  связку ключей
              блокируются; в противном случае он содержит  указатель  на  строку  с  именем  типа
              ключа,  а в аргументе arg4 содержится указатель на строку, описывающую ограничения,
              присущие типу. В Linux 4.12 из ограничений определено только «asymmetric»:

              builtin_trusted
                     Позволить прицеплять во встроенную связку  ключей  («.builtin_trusted_keys»)
                     только ключи, которые подписаны ключом.

              builtin_and_secondary_trusted
                     Позволить  прицеплять во вторичную связку ключей («.secondary_trusted_keys»)
                     только  ключи,  которые  подписаны  ключом,  или  как  расширение,  ключ  во
                     встроенную связку ключей, поскольку последний присоединен с первой.

              ключ_или_связка:ключ
              ключ_или_связка:ключ:chain
                     Если ключ задан идентификатором ключа типа «asymmetric», то разрешены только
                     ключи, подписанные этим ключом.

                     Если ключ задан идентификатором связки ключей, то  разрешены  только  ключи,
                     подписанные ключом из этой связки.

                     Если  указана  «:chain»  то  разрешены  ключи,  которые подписаны ключами из
                     связки назначения (то есть, связки ключей  с  идентификатором  из  аргумента
                     arg2).

              Заметим,  что  ограничение можно настроить для определённой связки только один раз;
              будучи назначенным, это нельзя изменить.

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

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

       При успешном выполнении возвращаемое значение зависит от используемой команды:

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

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

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

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

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

       KEYCTL_SET_REQKEY_KEYRING
              Идентификатор  предыдущей  связки  ключе  по  умолчанию, в которую неявно цепляются
              запрашиваемые ключи (одна из KEY_REQKEY_DEFL_USER_*).

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

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

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

       KEYCTL_DH_COMPUTE
              Количество  байт,  скопированных  в  буфер,  или требуемый размер буфера, если arg4
              равно 0.

       Остальные операции
              Ноль.

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

ОШИБКИ

       EACCES Запрошенная операция не разрешена.

       EAGAIN Значение operation равно KEYCTL_DH_COMPUTE и при  инициализации  модуля  шифрования
              возникла ошибка.

       EDEADLK
              Значение operation равно KEYCTL_LINK и запрошенная связь привела бы зацикливанию.

       EDEADLK
              Значение  operation  равно  KEYCTL_RESTRICT_KEYRING  и запрошенная связь привела бы
              зацикливанию.

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

       EEXIST Значение  operation равно KEYCTL_RESTRICT_KEYRING и связка ключей из аргумента arg2
              уже содержит набор ограничений.

       EFAULT Значение operation равно KEYCTL_DH_COMPUTE и возникла ошибки в одной  из  следующих
              операций:

              •  копирования    struct    keyctl_dh_params,   указанном   в   аргументе   arg2,из
                 пользовательского пространства

              •  копирования struct keyctl_kdf_params,  указанном  в  аргументе  arg5  не  равном
                 NULL,из   пользовательского   пространства   (случай,  когда  ядро  поддерживает
                 выполнение операции KDF над результатом операции DH)

              •  копирования данные, указанных в поле hashname с типом  struct  keyctl_kdf_params
                 из пользовательского пространства

              •  копирования  данные, указанных в поле otherinfo с типом struct keyctl_kdf_params
                 из пользовательского пространства и поле otherinfolen не равно нулю

              •  копирования результата в пользовательское пространство

       EINVAL Значение operation равно KEYCTL_SETPERM и в arg3 указан неверный бит прав.

       EINVAL operation was KEYCTL_SEARCH and the size of the description in arg4 (including  the
              terminating null byte) exceeded 4096 bytes.

       EINVAL size of the string (including the terminating null byte) specified in arg3 (the key
              type)  or arg4 (the key description)  exceeded the limit (32 bytes and  4096  bytes
              respectively).

       EINVAL (before Linux 4.12)
              Значение operation равно KEYCTL_DH_COMPUTE и аргумент arg5 не равен NULL.

       EINVAL Значение  operation  равно  KEYCTL_DH_COMPUTE  и указанный размер свёртки алгоритма
              хэширования равен нулю.

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

       EINVAL Значение operation равно KEYCTL_DH_COMPUTE и указанное имя  хэша  в  поле  hashname
              структуры  struct  keyctl_kdf_params,  на  которую указывает аргумент arg5, слишком
              велико (ограничение зависит от реализации и различно  в  разных  версиях  ядра,  но
              считается достаточно большим для всех допустимых имён алгоритмов).

       EINVAL Значение   operation  равно  KEYCTL_DH_COMPUTE  и  поле  __spare  структуры  struct
              keyctl_kdf_params, на которую указывает аргумент arg5, содержит ненулевое значение.

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

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

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

       ELOOP  Значение operation равно KEYCTL_LINK и запрошенная связь привела  бы  к  превышению
              количества вложенных друг в друга связок ключей.

       EMSGSIZE
              Значение    operation    равно   KEYCTL_DH_COMPUTE   и   длина   буфера   превышает
              KEYCTL_KDF_MAX_OUTPUT_LEN (в  данный  момент  равна  1024)  или  поле  otherinfolen
              структуры     struct     keyctl_kdf_parms,    переданной    в    arg5,    превышает
              KEYCTL_KDF_MAX_OI_LEN (в данный момент равно 64).

       ENFILE (before Linux 3.13)
              Значение operation равно KEYCTL_LINK и  связка  ключей  заполнена  (до  Linux  3.13
              доступное  место  для хранения связей связки ключей было ограничено одной страницей
              памяти; начиная с Linux 3.13 жёсткого ограничения нет).

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

       ENOENT Значение operation равно KEYCTL_DH_COMPUTE и алгоритм хэширования, указанный в поле
              hashname структуры struct keyctl_kdf_params, на которую указывает аргумент arg5, не
              найден.

       ENOENT Значение  operation  равно  KEYCTL_RESTRICT_KEYRING  и  тип  из  аргумента  arg3 не
              поддерживает ограничения установленным ключом сцепления.

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

       ENOKEY Значение operation равно KEYCTL_GET_KEYRING_ID, ключ, указанный arg2, не существует
              и значение arg3 равно нулю (то есть, не создавать ключ, если он не существует).

       ENOMEM При выполнении вызова одна из процедур выделения памяти ядра завершилась ошибкой.

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

       EOPNOTSUPP
              Значение  operation равно KEYCTL_READ и тип ключа не поддерживает чтение (например,
              тип "login").

       EOPNOTSUPP
              Значение operation равно KEYCTL_UPDATE и тип ключа не поддерживает обновление.

       EOPNOTSUPP
              Значение operation равно  KEYCTL_RESTRICT_KEYRING,  тип  из  аргумента  arg3  равен
              «asymmetric»   и   ключ,   указанный  в  определении  ограничения,  предоставляемый
              аргументом arg4, имеет тип не «asymmetric» или «keyring».

       EPERM  Значение operation равно KEYCTL_GET_PERSISTENT, в arg2 указан UID, отличающийся  от
              реального  или  действующего  UID  вызывающей  нити,  и вызывающий не имеет мандата
              CAP_SETUID.

       EPERM  Значение  operation  равно  KEYCTL_SESSION_TO_PARENT  и:  не  один  из  UID   (GID)
              родительского  процесса  не совпадают с действующим UID (GID) вызывающего процесса;
              UID существующей связки  ключей  сеанса  родителя  или  UID  связки  ключей  сеанса
              вызывающего  не  совпадает  с  действующим  UID  вызывающего;  родительский процесс
              состоит из нескольких нитей; родительский процесс это init(1) или нить ядра.

       ETIMEDOUT
              Значение operation равно  KEYCTL_DH_COMPUTE  и  истёк  срок  инициализации  модулей
              шифрования.

ВЕРСИИ

       Этот системный вызов впервые появился в Linux 2.6.10.

СТАНДАРТЫ

       Этот системный вызов является нестандартным расширением Linux.

ЗАМЕЧАНИЯ

       A  wrapper is provided in the libkeyutils library.  (The accompanying package provides the
       <keyutils.h> header file.)  However, rather than using  this  system  call  directly,  you
       probably  want  to  use  the  various  library  functions mentioned in the descriptions of
       individual operations above.

ПРИМЕРЫ

       Программа,  показанная  далее,  предоставляет  сокращённый  набор  возможностей  программы
       request-key(8)  из  пакета  keyutils.  Для  информирования  программа записывает различные
       данные в файл журнала.

       Согласно request_key(2),  программа  request-key(8)  вызывается  с  аргументами  командной
       строки,  которые  описывают  инициализируемый  ключ.  Программа  из  примера запрашивает и
       протоколирует эти аргументы. Программа авторизует на инициализацию запрашиваемого ключа  и
       затем инициализирует этот ключ.

       Следующий  сеанс оболочки показывает использование этой программы. В сеансе мы компилируем
       программу, а затем используем её как временную замены стандартной программы request-key(8)
       (заметим,  что  временное  отключение  стандартной  программы  request-key(8)  может  быть
       небезопасно на некоторых  системах).  После  того,  как  наша  программа  установлена,  мы
       показываем её работу с request_key(2) для запроса ключа.

           $ cc -o key_instantiate key_instantiate.c -lkeyutils
           $ sudo mv /sbin/request-key /sbin/request-key.backup
           $ sudo cp key_instantiate /sbin/request-key
           $ ./t_request_key user mykey somepayloaddata
           Идентификатор ключа равен 20d035bf
           $ sudo mv /sbin/request-key.backup /sbin/request-key

       Заглянув  в  файл  журнала,  созданный  программой,  мы увидим аргументы командной строки,
       переданные нашей программе:

           $ cat /tmp/key_instantiate.log
           Время: Mon Nov  7 13:06:47 2016

           Аргументы командной строки:
             argv[0]:            /sbin/request-key
             operation:          create
             key_to_instantiate: 20d035bf
             UID:                1000
             GID:                1000
             thread_keyring:     0
             process_keyring:    0
             session_keyring:    256e6a6

           Описание ключа:      user;1000;1000;3f010000;mykey
           Полезные данные ключа авторизации:     somepayloaddata
           Связка ключей назначения:  256e6a6
           Описание ключа авторизации: .request_key_auth;1000;1000;0b010000;20d035bf

       Последние несколько строк вывода показывают, что программа смогла получить:

       •  описание инициализируемого ключа, которое содержит имя ключа (mykey);

       •  полезные  данные  ключа  авторизации,  которые   содержат   данные   (somepayloaddata),
          переданные в request_key(2);

       •  связку ключей назначения, которая была указана в вызове request_key(2); и

       •  описание ключа авторизации, где мы можем увидеть, что имя ключа авторизации совпадает с
          идентификатором ключа, который будет инициализирован (20d035bf).

       Пример   программы   в   request_key(2)    задаёт    связку    ключей    назначения    как
       KEY_SPEC_SESSION_KEYRING.  Просмотрев  содержимое  /proc/keys,  мы  можем  увидеть, что он
       транслировался в идентификатор связки ключей назначения (0256e6a6), показанный  в  журнале
       выше;  мы  также  может увидеть только что созданный ключ с именем mykey и идентификатором
       20d035bf.

           $ cat /proc/keys | egrep 'mykey|256e6a6'
           0256e6a6 I--Q---  194 perm 3f030000  1000  1000 keyring  _ses: 3
           20d035bf I--Q---    1 perm 3f010000  1000  1000 user     mykey: 16

   Исходный код программы

       /* key_instantiate.c */

       #include <errno.h>
       #include <keyutils.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/types.h>
       #include <time.h>

       #ifndef KEY_SPEC_REQUESTOR_KEYRING
       #define KEY_SPEC_REQUESTOR_KEYRING      (-8)
       #endif

       int
       main(int argc, char *argv[])
       {
           int           akp_size;       /* Size of auth_key_payload */
           int           auth_key;
           char          dbuf[256];
           char          auth_key_payload[256];
           char          *operation;
           FILE          *fp;
           gid_t         gid;
           uid_t         uid;
           time_t        t;
           key_serial_t  key_to_instantiate, dest_keyring;
           key_serial_t  thread_keyring, process_keyring, session_keyring;

           if (argc != 8) {
               fprintf(stderr, "Usage: %s op key uid gid thread_keyring "
                               "process_keyring session_keyring\n", argv[0]);
               exit(EXIT_FAILURE);
           }

           fp = fopen("/tmp/key_instantiate.log", "w");
           if (fp == NULL)
               exit(EXIT_FAILURE);

           setbuf(fp, NULL);

           t = time(NULL);
           fprintf(fp, "Время: %s\n", ctime(&t));

           /*
            * ядро передаёт постоянный набор аргументов в программу,
            * которую выполняет execs; получаем их.
            */
           operation = argv[1];
           key_to_instantiate = atoi(argv[2]);
           uid = atoi(argv[3]);
           gid = atoi(argv[4]);
           thread_keyring = atoi(argv[5]);
           process_keyring = atoi(argv[6]);
           session_keyring = atoi(argv[7]);

           fprintf(fp, "Command line arguments:\n");
           fprintf(fp, "  argv[0]:            %s\n", argv[0]);
           fprintf(fp, "  operation:          %s\n", operation);
           fprintf(fp, "  key_to_instantiate: %jx\n",
                   (uintmax_t) key_to_instantiate);
           fprintf(fp, "  UID:                %jd\n", (intmax_t) uid);
           fprintf(fp, "  GID:                %jd\n", (intmax_t) gid);
           fprintf(fp, "  thread_keyring:     %jx\n",
                   (uintmax_t) thread_keyring);
           fprintf(fp, "  process_keyring:    %jx\n",
                   (uintmax_t) process_keyring);
           fprintf(fp, "  session_keyring:    %jx\n",
                   (uintmax_t) session_keyring);
           fprintf(fp, "\n");

           /*
            * выдаём право на инициализацию ключа с именем в argv[2]
            */
           if (keyctl(KEYCTL_ASSUME_AUTHORITY, key_to_instantiate) == -1) {
               fprintf(fp, "Ошибка KEYCTL_ASSUME_AUTHORITY: %s\n",
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           /*
            * получаем описание ключа, который был инициализирован
            */
           if (keyctl(KEYCTL_DESCRIBE, key_to_instantiate,
                       dbuf, sizeof(dbuf)) == -1) {
               fprintf(fp, "Ошибка KEYCTL_DESCRIBE: %s\n", strerror(errno));
               exit(EXIT_FAILURE);
           }

           fprintf(fp, "Описание ключа:      %s\n", dbuf);

           /*
            * получаем полезные данные ключа авторизации, который
            * в действительности содержит данные, переданные в request_key()
            */
           akp_size = keyctl(KEYCTL_READ, KEY_SPEC_REQKEY_AUTH_KEY,
                             auth_key_payload, sizeof(auth_key_payload));
           if (akp_size == -1) {
               fprintf(fp, "Ошибка KEYCTL_READ: %s\n", strerror(errno));
               exit(EXIT_FAILURE);
           }

           auth_key_payload[akp_size] = '\0';
           fprintf(fp, "Auth key payload:     %s\n", auth_key_payload);

           /*
            * For interest, get the ID of the authorization key and
            * display it.
            */
           auth_key = keyctl(KEYCTL_GET_KEYRING_ID,
                             KEY_SPEC_REQKEY_AUTH_KEY);
           if (auth_key == -1) {
               fprintf(fp, "KEYCTL_GET_KEYRING_ID failed: %s\n",
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           fprintf(fp, "Идентификатор ключа авторизации:          %jx\n", (uintmax_t) auth_key);

           /*
            * получим идентификатор ключа связки ключей назначения request_key(2).
            */
           dest_keyring = keyctl(KEYCTL_GET_KEYRING_ID,
                                 KEY_SPEC_REQUESTOR_KEYRING);
           if (dest_keyring == -1) {
               fprintf(fp, "Ошибка KEYCTL_GET_KEYRING_ID: %s\n",
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           fprintf(fp, "Связка ключей назначения:  %jx\n", (uintmax_t) dest_keyring);

           /*
            * Fetch the description of the authorization key. This
            * allows us to see the key type, UID, GID, permissions,
            * and description (name) of the key. Among other things,
            * we will see that the name of the key is a hexadecimal
            * string representing the ID of the key to be instantiated.
            */
           if (keyctl(KEYCTL_DESCRIBE, KEY_SPEC_REQKEY_AUTH_KEY,
                      dbuf, sizeof(dbuf)) == -1)
           {
               fprintf(fp, "KEYCTL_DESCRIBE failed: %s\n", strerror(errno));
               exit(EXIT_FAILURE);
           }

           fprintf(fp, "Описание ключа авторизации: %s\n", dbuf);

           /*
            * Instantiate the key using the callout data that was supplied
            * in the payload of the authorization key.
            */
           if (keyctl(KEYCTL_INSTANTIATE, key_to_instantiate,
                      auth_key_payload, akp_size + 1, dest_keyring) == -1)
           {
               fprintf(fp, "KEYCTL_INSTANTIATE failed: %s\n",
                       strerror(errno));
               exit(EXIT_FAILURE);
           }

           exit(EXIT_SUCCESS);
       }

СМ. ТАКЖЕ

       keyctl(1), add_key(2), request_key(2), keyctl(3), keyctl_assume_authority(3),
       keyctl_chown(3), keyctl_clear(3), keyctl_describe(3), keyctl_describe_alloc(3),
       keyctl_dh_compute(3), keyctl_dh_compute_alloc(3), keyctl_get_keyring_ID(3),
       keyctl_get_persistent(3), keyctl_get_security(3), keyctl_get_security_alloc(3),
       keyctl_instantiate(3), keyctl_instantiate_iov(3), keyctl_invalidate(3),
       keyctl_join_session_keyring(3), keyctl_link(3), keyctl_negate(3), keyctl_read(3),
       keyctl_read_alloc(3), keyctl_reject(3), keyctl_revoke(3), keyctl_search(3),
       keyctl_session_to_parent(3), keyctl_set_reqkey_keyring(3), keyctl_set_timeout(3),
       keyctl_setperm(3), keyctl_unlink(3), keyctl_update(3), recursive_key_scan(3),
       recursive_session_key_scan(3), capabilities(7), credentials(7), keyrings(7), keyutils(7),
       persistent-keyring(7), process-keyring(7), session-keyring(7), thread-keyring(7),
       user-keyring(7), user_namespaces(7), user-session-keyring(7), request-key(8)

       Файл из дерева исходного кода ядра Documentation/security/keys/ (до Linux 4.13 —
       Documentation/security/keys.txt).

ПЕРЕВОД

       Русский перевод этой страницы руководства был сделан Alex Nik <rage.iz.me@gmail.com>,
       Azamat Hackimov <azamat.hackimov@gmail.com>, Yuri Kozlov <yuray@komyakino.ru> и Иван
       Павлов <pavia00@gmail.com>

       Этот перевод является бесплатной документацией; прочитайте Стандартную общественную
       лицензию GNU версии 3 ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩ или более позднюю, чтобы
       узнать об условиях авторского права. Мы не несем НИКАКОЙ ОТВЕТСТВЕННОСТИ.

       Если вы обнаружите ошибки в переводе этой страницы руководства, пожалуйста, отправьте
       электронное письмо на ⟨man-pages-ru-talks@lists.sourceforge.net⟩.