[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>
This commit is contained in:
David Howells
2006-06-29 02:24:28 -07:00
committed by Linus Torvalds
parent 94583779e6
commit 4e54f08543
6 changed files with 108 additions and 30 deletions

View File

@ -1,6 +1,6 @@
/* request_key.c: request a key from userspace
*
* Copyright (C) 2004-5 Red Hat, Inc. All Rights Reserved.
* Copyright (C) 2004-6 Red Hat, Inc. All Rights Reserved.
* Written by David Howells (dhowells@redhat.com)
*
* This program is free software; you can redistribute it and/or
@ -33,7 +33,8 @@ DECLARE_WAIT_QUEUE_HEAD(request_key_conswq);
*/
static int call_sbin_request_key(struct key *key,
struct key *authkey,
const char *op)
const char *op,
void *aux)
{
struct task_struct *tsk = current;
key_serial_t prkey, sskey;
@ -127,6 +128,7 @@ error_alloc:
static struct key *__request_key_construction(struct key_type *type,
const char *description,
const char *callout_info,
void *aux,
unsigned long flags)
{
request_key_actor_t actor;
@ -164,7 +166,7 @@ static struct key *__request_key_construction(struct key_type *type,
actor = call_sbin_request_key;
if (type->request_key)
actor = type->request_key;
ret = actor(key, authkey, "create");
ret = actor(key, authkey, "create", aux);
if (ret < 0)
goto request_failed;
@ -258,8 +260,9 @@ alloc_failed:
*/
static struct key *request_key_construction(struct key_type *type,
const char *description,
struct key_user *user,
const char *callout_info,
void *aux,
struct key_user *user,
unsigned long flags)
{
struct key_construction *pcons;
@ -284,7 +287,7 @@ static struct key *request_key_construction(struct key_type *type,
}
/* see about getting userspace to construct the key */
key = __request_key_construction(type, description, callout_info,
key = __request_key_construction(type, description, callout_info, aux,
flags);
error:
kleave(" = %p", key);
@ -392,6 +395,7 @@ static void request_key_link(struct key *key, struct key *dest_keyring)
struct key *request_key_and_link(struct key_type *type,
const char *description,
const char *callout_info,
void *aux,
struct key *dest_keyring,
unsigned long flags)
{
@ -399,8 +403,9 @@ struct key *request_key_and_link(struct key_type *type,
struct key *key;
key_ref_t key_ref;
kenter("%s,%s,%s,%p,%lx",
type->name, description, callout_info, dest_keyring, flags);
kenter("%s,%s,%s,%p,%p,%lx",
type->name, description, callout_info, aux,
dest_keyring, flags);
/* search all the process keyrings for a key */
key_ref = search_process_keyrings(type, description, type->match,
@ -433,8 +438,8 @@ struct key *request_key_and_link(struct key_type *type,
/* ask userspace (returns NULL if it waited on a key
* being constructed) */
key = request_key_construction(type, description,
user, callout_info,
flags);
callout_info, aux,
user, flags);
if (key)
break;
@ -491,8 +496,27 @@ struct key *request_key(struct key_type *type,
const char *callout_info)
{
return request_key_and_link(type, description, callout_info, NULL,
KEY_ALLOC_IN_QUOTA);
NULL, KEY_ALLOC_IN_QUOTA);
} /* end request_key() */
EXPORT_SYMBOL(request_key);
/*****************************************************************************/
/*
* request a key with auxiliary data for the upcaller
* - search the process's keyrings
* - check the list of keys being created or updated
* - call out to userspace for a key if supplementary info was provided
*/
struct key *request_key_with_auxdata(struct key_type *type,
const char *description,
const char *callout_info,
void *aux)
{
return request_key_and_link(type, description, callout_info, aux,
NULL, KEY_ALLOC_IN_QUOTA);
} /* end request_key_with_auxdata() */
EXPORT_SYMBOL(request_key_with_auxdata);