diff options
| author | David Howells <dhowells@redhat.com> | 2006-06-29 05:24:28 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-06-29 13:26:20 -0400 |
| commit | 4e54f08543d05e519e601368571cc3787fefae96 (patch) | |
| tree | 0cd9d982e5bb25abcb9251d26c36ff11e7dc81a5 /security/keys | |
| parent | 94583779e6625154e8d7fce33d097ae7d089e9de (diff) | |
[PATCH] Keys: Allow in-kernel key requestor to pass auxiliary data to upcaller
The proposed NFS key type uses its own method of passing key requests to
userspace (upcalling) rather than invoking /sbin/request-key. This is
because the responsible userspace daemon should already be running and will
be contacted through rpc_pipefs.
This patch permits the NFS filesystem to pass auxiliary data to the upcall
operation (struct key_type::request_key) so that the upcaller can use a
pre-existing communications channel more easily.
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-By: Kevin Coffman <kwc@citi.umich.edu>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'security/keys')
| -rw-r--r-- | security/keys/internal.h | 1 | ||||
| -rw-r--r-- | security/keys/keyctl.c | 2 | ||||
| -rw-r--r-- | security/keys/request_key.c | 44 |
3 files changed, 36 insertions, 11 deletions
diff --git a/security/keys/internal.h b/security/keys/internal.h index 3c2877f0663e..1bb416f4bbce 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h | |||
| @@ -99,6 +99,7 @@ extern int install_process_keyring(struct task_struct *tsk); | |||
| 99 | extern struct key *request_key_and_link(struct key_type *type, | 99 | extern struct key *request_key_and_link(struct key_type *type, |
| 100 | const char *description, | 100 | const char *description, |
| 101 | const char *callout_info, | 101 | const char *callout_info, |
| 102 | void *aux, | ||
| 102 | struct key *dest_keyring, | 103 | struct key *dest_keyring, |
| 103 | unsigned long flags); | 104 | unsigned long flags); |
| 104 | 105 | ||
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 329411cf8768..d9ca15c109cc 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c | |||
| @@ -183,7 +183,7 @@ asmlinkage long sys_request_key(const char __user *_type, | |||
| 183 | } | 183 | } |
| 184 | 184 | ||
| 185 | /* do the search */ | 185 | /* do the search */ |
| 186 | key = request_key_and_link(ktype, description, callout_info, | 186 | key = request_key_and_link(ktype, description, callout_info, NULL, |
| 187 | key_ref_to_ptr(dest_ref), | 187 | key_ref_to_ptr(dest_ref), |
| 188 | KEY_ALLOC_IN_QUOTA); | 188 | KEY_ALLOC_IN_QUOTA); |
| 189 | if (IS_ERR(key)) { | 189 | if (IS_ERR(key)) { |
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 58d1efd4fc2c..f573ac189a0a 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | /* request_key.c: request a key from userspace | 1 | /* request_key.c: request a key from userspace |
| 2 | * | 2 | * |
| 3 | * Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved. | 3 | * Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved. |
| 4 | * Written by David Howells (dhowells@redhat.com) | 4 | * Written by David Howells (dhowells@redhat.com) |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or | 6 | * This program is free software; you can redistribute it and/or |
| @@ -33,7 +33,8 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq); | |||
| 33 | */ | 33 | */ |
| 34 | static int call_sbin_request_key(struct key *key, | 34 | static int call_sbin_request_key(struct key *key, |
| 35 | struct key *authkey, | 35 | struct key *authkey, |
| 36 | const char *op) | 36 | const char *op, |
| 37 | void *aux) | ||
| 37 | { | 38 | { |
| 38 | struct task_struct *tsk = current; | 39 | struct task_struct *tsk = current; |
| 39 | key_serial_t prkey, sskey; | 40 | key_serial_t prkey, sskey; |
| @@ -127,6 +128,7 @@ error_alloc: | |||
| 127 | static struct key *__request_key_construction(struct key_type *type, | 128 | static struct key *__request_key_construction(struct key_type *type, |
| 128 | const char *description, | 129 | const char *description, |
| 129 | const char *callout_info, | 130 | const char *callout_info, |
| 131 | void *aux, | ||
| 130 | unsigned long flags) | 132 | unsigned long flags) |
| 131 | { | 133 | { |
| 132 | request_key_actor_t actor; | 134 | request_key_actor_t actor; |
| @@ -164,7 +166,7 @@ static struct key *__request_key_construction(struct key_type *type, | |||
| 164 | actor = call_sbin_request_key; | 166 | actor = call_sbin_request_key; |
| 165 | if (type->request_key) | 167 | if (type->request_key) |
| 166 | actor = type->request_key; | 168 | actor = type->request_key; |
| 167 | ret = actor(key, authkey, "create"); | 169 | ret = actor(key, authkey, "create", aux); |
| 168 | if (ret < 0) | 170 | if (ret < 0) |
| 169 | goto request_failed; | 171 | goto request_failed; |
| 170 | 172 | ||
| @@ -258,8 +260,9 @@ alloc_failed: | |||
| 258 | */ | 260 | */ |
| 259 | static struct key *request_key_construction(struct key_type *type, | 261 | static struct key *request_key_construction(struct key_type *type, |
| 260 | const char *description, | 262 | const char *description, |
| 261 | struct key_user *user, | ||
| 262 | const char *callout_info, | 263 | const char *callout_info, |
| 264 | void *aux, | ||
| 265 | struct key_user *user, | ||
| 263 | unsigned long flags) | 266 | unsigned long flags) |
| 264 | { | 267 | { |
| 265 | struct key_construction *pcons; | 268 | struct key_construction *pcons; |
| @@ -284,7 +287,7 @@ static struct key *request_key_construction(struct key_type *type, | |||
| 284 | } | 287 | } |
| 285 | 288 | ||
| 286 | /* see about getting userspace to construct the key */ | 289 | /* see about getting userspace to construct the key */ |
| 287 | key = __request_key_construction(type, description, callout_info, | 290 | key = __request_key_construction(type, description, callout_info, aux, |
| 288 | flags); | 291 | flags); |
| 289 | error: | 292 | error: |
| 290 | kleave(" = %p", key); | 293 | kleave(" = %p", key); |
| @@ -392,6 +395,7 @@ static void request_key_link(struct key *key, struct key *dest_keyring) | |||
| 392 | struct key *request_key_and_link(struct key_type *type, | 395 | struct key *request_key_and_link(struct key_type *type, |
| 393 | const char *description, | 396 | const char *description, |
| 394 | const char *callout_info, | 397 | const char *callout_info, |
| 398 | void *aux, | ||
| 395 | struct key *dest_keyring, | 399 | struct key *dest_keyring, |
| 396 | unsigned long flags) | 400 | unsigned long flags) |
| 397 | { | 401 | { |
| @@ -399,8 +403,9 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 399 | struct key *key; | 403 | struct key *key; |
| 400 | key_ref_t key_ref; | 404 | key_ref_t key_ref; |
| 401 | 405 | ||
| 402 | kenter("%s,%s,%s,%p,%lx", | 406 | kenter("%s,%s,%s,%p,%p,%lx", |
| 403 | type->name, description, callout_info, dest_keyring, flags); | 407 | type->name, description, callout_info, aux, |
| 408 | dest_keyring, flags); | ||
| 404 | 409 | ||
| 405 | /* search all the process keyrings for a key */ | 410 | /* search all the process keyrings for a key */ |
| 406 | key_ref = search_process_keyrings(type, description, type->match, | 411 | key_ref = search_process_keyrings(type, description, type->match, |
| @@ -433,8 +438,8 @@ struct key *request_key_and_link(struct key_type *type, | |||
| 433 | /* ask userspace (returns NULL if it waited on a key | 438 | /* ask userspace (returns NULL if it waited on a key |
| 434 | * being constructed) */ | 439 | * being constructed) */ |
| 435 | key = request_key_construction(type, description, | 440 | key = request_key_construction(type, description, |
| 436 | user, callout_info, | 441 | callout_info, aux, |
| 437 | flags); | 442 | user, flags); |
| 438 | if (key) | 443 | if (key) |
| 439 | break; | 444 | break; |
| 440 | 445 | ||
| @@ -491,8 +496,27 @@ struct key *request_key(struct key_type *type, | |||
| 491 | const char *callout_info) | 496 | const char *callout_info) |
| 492 | { | 497 | { |
| 493 | return request_key_and_link(type, description, callout_info, NULL, | 498 | return request_key_and_link(type, description, callout_info, NULL, |
| 494 | KEY_ALLOC_IN_QUOTA); | 499 | NULL, KEY_ALLOC_IN_QUOTA); |
| 495 | 500 | ||
| 496 | } /* end request_key() */ | 501 | } /* end request_key() */ |
| 497 | 502 | ||
| 498 | EXPORT_SYMBOL(request_key); | 503 | EXPORT_SYMBOL(request_key); |
| 504 | |||
| 505 | /*****************************************************************************/ | ||
| 506 | /* | ||
| 507 | * request a key with auxiliary data for the upcaller | ||
| 508 | * - search the process's keyrings | ||
| 509 | * - check the list of keys being created or updated | ||
| 510 | * - call out to userspace for a key if supplementary info was provided | ||
| 511 | */ | ||
| 512 | struct key *request_key_with_auxdata(struct key_type *type, | ||
| 513 | const char *description, | ||
| 514 | const char *callout_info, | ||
| 515 | void *aux) | ||
| 516 | { | ||
| 517 | return request_key_and_link(type, description, callout_info, aux, | ||
| 518 | NULL, KEY_ALLOC_IN_QUOTA); | ||
| 519 | |||
| 520 | } /* end request_key_with_auxdata() */ | ||
| 521 | |||
| 522 | EXPORT_SYMBOL(request_key_with_auxdata); | ||
