summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-07-16 16:41:16 +0100
committerDavid Howells <dhowells@redhat.com>2020-07-16 21:51:11 +0100
commit024634145073e88eb4c33bc95938e2e6ae02d17b (patch)
treec68632a29a76f58858b5a7221d108b94e30257ac
parent2f5e22538458426e1dac20a8dd62b750847ad0d7 (diff)
downloadkeyutils-024634145073e88eb4c33bc95938e2e6ae02d17b.tar.gz
Provide a container keyring keyctl
-rw-r--r--keyctl.c43
-rw-r--r--keyutils.c5
-rw-r--r--keyutils.h6
3 files changed, 47 insertions, 7 deletions
diff --git a/keyctl.c b/keyctl.c
index 5ae50b6..3beea46 100644
--- a/keyctl.c
+++ b/keyctl.c
@@ -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
diff --git a/keyutils.c b/keyutils.c
index 980de93..4e41362 100644
--- a/keyutils.c
+++ b/keyutils.c
@@ -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
diff --git a/keyutils.h b/keyutils.h
index 44cf667..6b14045 100644
--- a/keyutils.h
+++ b/keyutils.h
@@ -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