diff options
author | David Howells <dhowells@redhat.com> | 2020-07-16 16:41:16 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2020-07-16 21:51:11 +0100 |
commit | 024634145073e88eb4c33bc95938e2e6ae02d17b (patch) | |
tree | c68632a29a76f58858b5a7221d108b94e30257ac | |
parent | 2f5e22538458426e1dac20a8dd62b750847ad0d7 (diff) | |
download | keyutils-024634145073e88eb4c33bc95938e2e6ae02d17b.tar.gz |
Provide a container keyring keyctl
-rw-r--r-- | keyctl.c | 43 | ||||
-rw-r--r-- | keyutils.c | 5 | ||||
-rw-r--r-- | keyutils.h | 6 |
3 files changed, 47 insertions, 7 deletions
@@ -85,6 +85,7 @@ static nr void act_keyctl_pkey_verify(int argc, char *argv[]); static nr void act_keyctl_move(int argc, char *argv[]); static nr void act_keyctl_supports(int argc, char *argv[]); static nr void act_keyctl_grant(int argc, char *argv[]); +static nr void act_keyctl_get_container(int argc, char *argv[]); static const struct command commands[] = { { act_keyctl___version, "--version", "" }, @@ -96,6 +97,7 @@ static const struct command commands[] = { { act_keyctl_dh_compute, "dh_compute", "<private> <prime> <base>" }, { act_keyctl_dh_compute_kdf, "dh_compute_kdf", "<private> <prime> <base> <len> <hash_name>" }, { act_keyctl_dh_compute_kdf_oi, "dh_compute_kdf_oi", "[-x] <private> <prime> <base> <len> <hash_name>" }, + { act_keyctl_get_container, "get_container", "<userns-fd> <destkeyring>" }, { act_keyctl_get_persistent, "get_persistent", "<keyring> [<uid>]" }, { act_keyctl_grant, "grant", "<key> <subject> <perms>" }, { act_keyctl_id, "id", "<key>" }, @@ -170,7 +172,7 @@ void error(const char *msg) /*****************************************************************************/ /* - * + * */ int main(int argc, char *argv[]) { @@ -310,7 +312,7 @@ void hex2bin(void **_data, size_t *_datalen, bool as_hex) { unsigned char *buf, *q, h, l; char *p, *end; - + if (!as_hex || *_datalen == 0) return; @@ -2295,6 +2297,7 @@ static const struct capability_def capabilities[] = { { "notify", 1, KEYCTL_CAPS1_NOTIFICATIONS }, { "acl", 1, KEYCTL_CAPS1_ACL }, { "grant", 1, KEYCTL_CAPS1_GRANT_PERMISSION }, + { "container_keyring", 1, KEYCTL_CAPS1_CONTAINER_KEYRINGS }, {} }; @@ -2343,7 +2346,7 @@ static void act_keyctl_grant(int argc, char *argv[]) enum key_ace_subject_type type; key_serial_t key; unsigned subj, mask = 0; - char *id, *perms; + char *id, *perms, *p; if (argc != 4) format(); @@ -2364,15 +2367,21 @@ static void act_keyctl_grant(int argc, char *argv[]) } else if (strcmp(id, "pos") == 0) { type = KEY_ACE_SUBJ_STANDARD; subj = KEY_ACE_POSSESSOR; + } else if (strncmp(id, "cont:", 5) == 0) { + type = KEY_ACE_SUBJ_CONTAINER; + subj = strtoul(id + 5, &p, 0); + if (*p) { + fprintf(stderr, "Invalid container ref\n"); + exit(2); + } } else { fprintf(stderr, "Invalid subject type\n"); exit(2); } if (isdigit(*perms)) { - char *p; unsigned long ltmp = strtoul(perms, &p, 0); - if (ltmp & ~(unsigned long)KEY_ACE__PERMS) + if (sizeof(ltmp) > sizeof(mask) && ltmp >> 32) goto invalid_permits; if (*p) goto invalid_permits; @@ -2389,7 +2398,7 @@ static void act_keyctl_grant(int argc, char *argv[]) case 'l': mask |= KEY_ACE_LINK; break; case 'I': mask |= KEY_ACE_INVAL; break; case 'R': mask |= KEY_ACE_REVOKE; break; - case 'S': mask |= KEY_ACE_SET_SECURITY; break; + case 'S': mask |= KEY_ACE_SETSEC; break; case 'j': mask |= KEY_ACE_JOIN; break; case 'c': mask |= KEY_ACE_CLEAR; break; default: goto invalid_permits; @@ -2407,6 +2416,28 @@ invalid_permits: exit(2); } +/* + * Get a container keyring and link it to the specified destination keyring. + */ +static void act_keyctl_get_container(int argc, char *argv[]) +{ + key_serial_t dest, id; + int fd; + + if (argc != 3) + format(); + + fd = atoi(argv[1]); + dest = get_key_id(argv[2]); + + id = keyctl_get_container_keyring(fd, dest); + if (id < 0) + error("keyctl_get_container_keyring"); + + printf("%d\n", id); + exit(0); +} + /*****************************************************************************/ /* * parse a key identifier @@ -396,6 +396,11 @@ long keyctl_grant_permission(key_serial_t id, enum key_ace_subject_type type, return keyctl(KEYCTL_GRANT_PERMISSION, id, type, subject, perm); } +long keyctl_get_container_keyring(int container_fd, key_serial_t destringid) +{ + return keyctl(KEYCTL_GET_CONTAINER_KEYRING, container_fd, destringid); +} + /*****************************************************************************/ /* * fetch key description into an allocated buffer @@ -50,6 +50,7 @@ typedef int32_t key_serial_t; */ enum key_ace_subject_type { KEY_ACE_SUBJ_STANDARD = 0, /* subject is one of key_ace_standard_subject */ + KEY_ACE_SUBJ_CONTAINER = 1, /* subject is a container fd */ nr__key_ace_subject_type }; @@ -66,7 +67,7 @@ enum key_ace_standard_subject { #define KEY_ACE_WRITE 0x00000004 /* Can update/modify the key content */ #define KEY_ACE_SEARCH 0x00000008 /* Can find the key by search */ #define KEY_ACE_LINK 0x00000010 /* Can make a link to the key */ -#define KEY_ACE_SET_SECURITY 0x00000020 /* Can set owner, group, ACL */ +#define KEY_ACE_SETSEC 0x00000020 /* Can set owner, group, ACL, restrictions */ #define KEY_ACE_INVAL 0x00000040 /* Can invalidate the key */ #define KEY_ACE_REVOKE 0x00000080 /* Can revoke the key */ #define KEY_ACE_JOIN 0x00000100 /* Can join keyring */ @@ -145,6 +146,7 @@ typedef uint32_t key_perm_t; #define KEYCTL_CAPABILITIES 31 /* Find capabilities of keyrings subsystem */ #define KEYCTL_WATCH_KEY 32 /* Watch a key or ring of keys for changes */ #define KEYCTL_GRANT_PERMISSION 33 /* Grant a permit to a key */ +#define KEYCTL_GET_CONTAINER_KEYRING 34 /* Get a container keyring */ /* keyctl structures */ struct keyctl_dh_params { @@ -204,6 +206,7 @@ struct keyctl_pkey_params { #define KEYCTL_CAPS1_NOTIFICATIONS 0x04 /* Keys generate watchable notifications */ #define KEYCTL_CAPS1_ACL 0x08 /* Keys have ACLs rather than a p-u-g-o bitmask */ #define KEYCTL_CAPS1_GRANT_PERMISSION 0x10 /* KEYCTL_GRANT_PERMISSION is supported */ +#define KEYCTL_CAPS1_CONTAINER_KEYRINGS 0x20 /* Container keyrings are supported */ /* * syscall wrappers @@ -294,6 +297,7 @@ extern long keyctl_capabilities(unsigned char *buffer, size_t buflen); extern long keyctl_watch_key(key_serial_t id, int watch_queue_fd, int watch_id); extern long keyctl_grant_permission(key_serial_t id, enum key_ace_subject_type type, unsigned int subject, unsigned int perm); +extern long keyctl_get_container_keyring(int container_fd, key_serial_t destringid); /* * utilities |