diff options
Diffstat (limited to '')
-rw-r--r-- | man2/request_key.2 | 562 |
1 files changed, 562 insertions, 0 deletions
diff --git a/man2/request_key.2 b/man2/request_key.2 new file mode 100644 index 0000000..80187d1 --- /dev/null +++ b/man2/request_key.2 @@ -0,0 +1,562 @@ +.\" Copyright (C) 2006 Red Hat, Inc. All Rights Reserved. +.\" Written by David Howells (dhowells@redhat.com) +.\" and Copyright (C) 2016 Michael Kerrisk <mtk.man-pages@gmail.com> +.\" +.\" SPDX-License-Identifier: GPL-2.0-or-later +.\" +.TH request_key 2 2023-05-03 "Linux man-pages 6.05.01" +.SH NAME +request_key \- request a key from the kernel's key management facility +.SH LIBRARY +Linux Key Management Utilities +.RI ( libkeyutils ", " \-lkeyutils ) +.SH SYNOPSIS +.nf +.B #include <keyutils.h> +.PP +.BI "key_serial_t request_key(const char *" type ", const char *" description , +.BI " const char *_Nullable " callout_info , +.BI " key_serial_t " dest_keyring ); +.fi +.SH DESCRIPTION +.BR request_key () +attempts to find a key of the given +.I type +with a description (name) that matches the specified +.IR description . +If such a key could not be found, then the key is optionally created. +If the key is found or created, +.BR request_key () +attaches it to the keyring whose ID is specified in +.I dest_keyring +and returns the key's serial number. +.PP +.BR request_key () +first recursively searches for a matching key in all of the keyrings +attached to the calling process. +The keyrings are searched in the order: thread-specific keyring, +process-specific keyring, and then session keyring. +.PP +If +.BR request_key () +is called from a program invoked by +.BR request_key () +on behalf of some other process to generate a key, then the keyrings of that +other process will be searched next, +using that other process's user ID, group ID, +supplementary group IDs, and security context to determine access. +.\" David Howells: we can then have an arbitrarily long sequence +.\" of "recursive" request-key upcalls. There is no limit, other +.\" than number of PIDs, etc. +.PP +The search of the keyring tree is breadth-first: +the keys in each keyring searched are checked for a match before any child +keyrings are recursed into. +Only keys for which the caller has +.I search +permission be found, and only keyrings for which the caller has +.I search +permission may be searched. +.PP +If the key is not found and +.I callout +is NULL, then the call fails with the error +.BR ENOKEY . +.PP +If the key is not found and +.I callout +is not NULL, then the kernel attempts to invoke a user-space +program to instantiate the key. +The details are given below. +.PP +The +.I dest_keyring +serial number may be that of a valid keyring for which the caller has +.I write +permission, or it may be one of the following special keyring IDs: +.TP +.B KEY_SPEC_THREAD_KEYRING +This specifies the caller's thread-specific keyring (see +.BR thread\-keyring (7)). +.TP +.B KEY_SPEC_PROCESS_KEYRING +This specifies the caller's process-specific keyring (see +.BR process\-keyring (7)). +.TP +.B KEY_SPEC_SESSION_KEYRING +This specifies the caller's session-specific keyring (see +.BR session\-keyring (7)). +.TP +.B KEY_SPEC_USER_KEYRING +This specifies the caller's UID-specific keyring (see +.BR user\-keyring (7)). +.TP +.B KEY_SPEC_USER_SESSION_KEYRING +This specifies the caller's UID-session keyring (see +.BR user\-session\-keyring (7)). +.PP +When the +.I dest_keyring +is specified as 0 +and no key construction has been performed, +then no additional linking is done. +.PP +Otherwise, if +.I dest_keyring +is 0 and a new key is constructed, the new key will be linked +to the "default" keyring. +More precisely, when the kernel tries to determine to which keyring the +newly constructed key should be linked, +it tries the following keyrings, +beginning with the keyring set via the +.BR keyctl (2) +.B KEYCTL_SET_REQKEY_KEYRING +operation and continuing in the order shown below +until it finds the first keyring that exists: +.IP \[bu] 3 +.\" 8bbf4976b59fc9fc2861e79cab7beb3f6d647640 +The requestor keyring +.RB ( KEY_REQKEY_DEFL_REQUESTOR_KEYRING , +since Linux 2.6.29). +.\" FIXME +.\" Actually, is the preceding point correct? +.\" If I understand correctly, we'll only get here if +.\" 'dest_keyring' is zero, in which case KEY_REQKEY_DEFL_REQUESTOR_KEYRING +.\" won't refer to a keyring. Have I misunderstood? +.IP \[bu] +The thread-specific keyring +.RB ( KEY_REQKEY_DEFL_THREAD_KEYRING ; +see +.BR thread\-keyring (7)). +.IP \[bu] +The process-specific keyring +.RB ( KEY_REQKEY_DEFL_PROCESS_KEYRING ; +see +.BR process\-keyring (7)). +.IP \[bu] +The session-specific keyring +.RB ( KEY_REQKEY_DEFL_SESSION_KEYRING ; +see +.BR session\-keyring (7)). +.IP \[bu] +The session keyring for the process's user ID +.RB ( KEY_REQKEY_DEFL_USER_SESSION_KEYRING ; +see +.BR user\-session\-keyring (7)). +This keyring is expected to always exist. +.IP \[bu] +The UID-specific keyring +.RB ( KEY_REQKEY_DEFL_USER_KEYRING ; +see +.BR user\-keyring (7)). +This keyring is also expected to always exist. +.\" mtk: Are there circumstances where the user sessions and UID-specific +.\" keyrings do not exist? +.\" +.\" David Howells: +.\" The uid keyrings don't exist until someone tries to access them - +.\" at which point they're both created. When you log in, pam_keyinit +.\" creates a link to your user keyring in the session keyring it just +.\" created, thereby creating the user and user-session keyrings. +.\" +.\" and David elaborated that "access" means: +.\" +.\" It means lookup_user_key() was passed KEY_LOOKUP_CREATE. So: +.\" +.\" add_key() - destination keyring +.\" request_key() - destination keyring +.\" KEYCTL_GET_KEYRING_ID - if create arg is true +.\" KEYCTL_CLEAR +.\" KEYCTL_LINK - both args +.\" KEYCTL_SEARCH - destination keyring +.\" KEYCTL_CHOWN +.\" KEYCTL_SETPERM +.\" KEYCTL_SET_TIMEOUT +.\" KEYCTL_INSTANTIATE - destination keyring +.\" KEYCTL_INSTANTIATE_IOV - destination keyring +.\" KEYCTL_NEGATE - destination keyring +.\" KEYCTL_REJECT - destination keyring +.\" KEYCTL_GET_PERSISTENT - destination keyring +.\" +.\" will all create a keyring under some circumstances. Whereas the rest, +.\" such as KEYCTL_GET_SECURITY, KEYCTL_READ and KEYCTL_REVOKE, won't. +.PP +If the +.BR keyctl (2) +.B KEYCTL_SET_REQKEY_KEYRING +operation specifies +.B KEY_REQKEY_DEFL_DEFAULT +(or no +.B KEYCTL_SET_REQKEY_KEYRING +operation is performed), +then the kernel looks for a keyring +starting from the beginning of the list. +.\" +.SS Requesting user-space instantiation of a key +If the kernel cannot find a key matching +.I type +and +.IR description , +and +.I callout +is not NULL, then the kernel attempts to invoke a user-space +program to instantiate a key with the given +.I type +and +.IR description . +In this case, the following steps are performed: +.IP (1) 5 +The kernel creates an uninstantiated key, U, with the requested +.I type +and +.IR description . +.IP (2) +The kernel creates an authorization key, V, +.\" struct request_key_auth, defined in security/keys/internal.h +that refers to the key U and records the facts that the caller of +.BR request_key () +is: +.RS +.IP (2.1) 7 +the context in which the key U should be instantiated and secured, and +.IP (2.2) +the context from which associated key requests may be satisfied. +.RE +.IP +The authorization key is constructed as follows: +.RS +.IP \[bu] 3 +The key type is +.IR """.request_key_auth""" . +.IP \[bu] +The key's UID and GID are the same as the corresponding filesystem IDs +of the requesting process. +.IP \[bu] +The key grants +.IR view , +.IR read , +and +.I search +permissions to the key possessor as well as +.I view +permission for the key user. +.IP \[bu] +The description (name) of the key is the hexadecimal +string representing the ID of the key that is to be instantiated +in the requesting program. +.IP \[bu] +The payload of the key is taken from the data specified in +.IR callout_info . +.IP \[bu] +Internally, the kernel also records the PID of the process that called +.BR request_key (). +.RE +.IP (3) +The kernel creates a process that executes a user-space service such as +.BR request\-key (8) +with a new session keyring that contains a link to the authorization key, V. +.\" The request\-key(8) program can be invoked in circumstances *other* than +.\" when triggered by request_key(2). For example, upcalls from places such +.\" as the DNS resolver. +.IP +This program is supplied with the following command-line arguments: +.RS +.IP [0] 5 +The string +.IR """/sbin/request\-key""" . +.IP [1] +The string +.I """create""" +(indicating that a key is to be created). +.IP [2] +The ID of the key that is to be instantiated. +.IP [3] +The filesystem UID of the caller of +.BR request_key (). +.IP [4] +The filesystem GID of the caller of +.BR request_key (). +.IP [5] +The ID of the thread keyring of the caller of +.BR request_key (). +This may be zero if that keyring hasn't been created. +.IP [6] +The ID of the process keyring of the caller of +.BR request_key (). +This may be zero if that keyring hasn't been created. +.IP [7] +The ID of the session keyring of the caller of +.BR request_key (). +.RE +.IP +.IR Note : +each of the command-line arguments that is a key ID is encoded in +.I decimal +(unlike the key IDs shown in +.IR /proc/keys , +which are shown as hexadecimal values). +.IP (4) +The program spawned in the previous step: +.RS +.IP \[bu] 3 +Assumes the authority to instantiate the key U using the +.BR keyctl (2) +.B KEYCTL_ASSUME_AUTHORITY +operation (typically via the +.BR keyctl_assume_authority (3) +function). +.IP \[bu] +Obtains the callout data from the payload of the authorization key V +(using the +.BR keyctl (2) +.B KEYCTL_READ +operation (or, more commonly, the +.BR keyctl_read (3) +function) with a key ID value of +.BR KEY_SPEC_REQKEY_AUTH_KEY ). +.IP \[bu] +Instantiates the key +(or execs another program that performs that task), +specifying the payload and destination keyring. +(The destination keyring that the requestor specified when calling +.BR request_key () +can be accessed using the special key ID +.BR KEY_SPEC_REQUESTOR_KEYRING .) +.\" Should an instantiating program be using KEY_SPEC_REQUESTOR_KEYRING? +.\" I couldn't find a use in the keyutils git repo. +.\" According to David Howells: +.\" * This feature is provided, but not used at the moment. +.\" * A key added to that ring is then owned by the requester +Instantiation is performed using the +.BR keyctl (2) +.B KEYCTL_INSTANTIATE +operation (or, more commonly, the +.BR keyctl_instantiate (3) +function). +At this point, the +.BR request_key () +call completes, and the requesting program can continue execution. +.RE +.PP +If these steps are unsuccessful, then an +.B ENOKEY +error will be returned to the caller of +.BR request_key () +and a temporary, negatively instantiated key will be installed +in the keyring specified by +.IR dest_keyring . +This will expire after a few seconds, but will cause subsequent calls to +.BR request_key () +to fail until it does. +The purpose of this negatively instantiated key is to prevent +(possibly different) processes making repeated requests +(that require expensive +.BR request\-key (8) +upcalls) for a key that can't (at the moment) be positively instantiated. +.PP +Once the key has been instantiated, the authorization key +.RB ( KEY_SPEC_REQKEY_AUTH_KEY ) +is revoked, and the destination keyring +.RB ( KEY_SPEC_REQUESTOR_KEYRING ) +is no longer accessible from the +.BR request\-key (8) +program. +.PP +If a key is created, then\[em]regardless of whether it is a valid key or +a negatively instantiated key\[em]it will displace any other key with +the same type and description from the keyring specified in +.IR dest_keyring . +.SH RETURN VALUE +On success, +.BR request_key () +returns the serial number of the key it found or caused to be created. +On error, \-1 is returned and +.I errno +is set to indicate the error. +.SH ERRORS +.TP +.B EACCES +The keyring wasn't available for modification by the user. +.TP +.B EDQUOT +The key quota for this user would be exceeded by creating this key or linking +it to the keyring. +.TP +.B EFAULT +One of +.IR type , +.IR description , +or +.I callout_info +points outside the process's accessible address space. +.TP +.B EINTR +The request was interrupted by a signal; see +.BR signal (7). +.TP +.B EINVAL +The size of the string (including the terminating null byte) specified in +.I type +or +.I description +exceeded the limit (32 bytes and 4096 bytes respectively). +.TP +.B EINVAL +The size of the string (including the terminating null byte) specified in +.I callout_info +exceeded the system page size. +.TP +.B EKEYEXPIRED +An expired key was found, but no replacement could be obtained. +.TP +.B EKEYREJECTED +The attempt to generate a new key was rejected. +.TP +.B EKEYREVOKED +A revoked key was found, but no replacement could be obtained. +.TP +.B ENOKEY +No matching key was found. +.TP +.B ENOMEM +Insufficient memory to create a key. +.TP +.B EPERM +The +.I type +argument started with a period (\[aq].\[aq]). +.SH STANDARDS +Linux. +.SH HISTORY +Linux 2.6.10. +.PP +The ability to instantiate keys upon request was added +.\" commit 3e30148c3d524a9c1c63ca28261bc24c457eb07a +in Linux 2.6.13. +.SH EXAMPLES +The program below demonstrates the use of +.BR request_key (). +The +.IR type , +.IR description , +and +.I callout_info +arguments for the system call are taken from the values +supplied in the command-line arguments. +The call specifies the session keyring as the target keyring. +.PP +In order to demonstrate this program, +we first create a suitable entry in the file +.IR /etc/request\-key.conf . +.PP +.in +4n +.EX +$ sudo sh +# \fBecho \[aq]create user mtk:* * /bin/keyctl instantiate %k %c %S\[aq] \e\fP + \fB> /etc/request\-key.conf\fP +# \fBexit\fP +.EE +.in +.PP +This entry specifies that when a new "user" key with the prefix +"mtk:" must be instantiated, that task should be performed via the +.BR keyctl (1) +command's +.B instantiate +operation. +The arguments supplied to the +.B instantiate +operation are: +the ID of the uninstantiated key +.RI ( %k ); +the callout data supplied to the +.BR request_key () +call +.RI ( %c ); +and the session keyring +.RI ( %S ) +of the requestor (i.e., the caller of +.BR request_key ()). +See +.BR request\-key.conf (5) +for details of these +.I % +specifiers. +.PP +Then we run the program and check the contents of +.I /proc/keys +to verify that the requested key has been instantiated: +.PP +.in +4n +.EX +$ \fB./t_request_key user mtk:key1 "Payload data"\fP +$ \fBgrep \[aq]2dddaf50\[aq] /proc/keys\fP +2dddaf50 I\-\-Q\-\-\- 1 perm 3f010000 1000 1000 user mtk:key1: 12 +.EE +.in +.PP +For another example of the use of this program, see +.BR keyctl (2). +.SS Program source +\& +.\" SRC BEGIN (t_request_key.c) +.EX +/* 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, "Usage: %s type description callout\-data\en", + 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\en", (uintmax_t) key); +\& + exit(EXIT_SUCCESS); +} +.EE +.\" SRC END +.SH SEE ALSO +.ad l +.nh +.BR keyctl (1), +.BR add_key (2), +.BR keyctl (2), +.BR keyctl (3), +.BR capabilities (7), +.BR keyrings (7), +.BR keyutils (7), +.BR persistent\-keyring (7), +.BR process\-keyring (7), +.BR session\-keyring (7), +.BR thread\-keyring (7), +.BR user\-keyring (7), +.BR user\-session\-keyring (7), +.BR request\-key (8) +.PP +The kernel source files +.I Documentation/security/keys/core.rst +and +.I Documentation/keys/request\-key.rst +(or, before Linux 4.13, in the files +.\" commit b68101a1e8f0263dbc7b8375d2a7c57c6216fb76 +.I Documentation/security/keys.txt +and +.\" commit 3db38ed76890565772fcca3279cc8d454ea6176b +.IR Documentation/security/keys\-request\-key.txt ). |