[PATCH] USB: ioctl compat for usblp.c
[linux-2.6/mini2440.git] / security / keys / request_key_auth.c
bloba8e4069d48cbf93d91b6bcab3ee173549139221c
1 /* request_key_auth.c: request key authorisation controlling key def
3 * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * See Documentation/keys-request-key.txt
14 #include <linux/module.h>
15 #include <linux/sched.h>
16 #include <linux/err.h>
17 #include <linux/seq_file.h>
18 #include "internal.h"
20 static int request_key_auth_instantiate(struct key *, const void *, size_t);
21 static void request_key_auth_describe(const struct key *, struct seq_file *);
22 static void request_key_auth_destroy(struct key *);
25 * the request-key authorisation key type definition
27 struct key_type key_type_request_key_auth = {
28 .name = ".request_key_auth",
29 .def_datalen = sizeof(struct request_key_auth),
30 .instantiate = request_key_auth_instantiate,
31 .describe = request_key_auth_describe,
32 .destroy = request_key_auth_destroy,
35 /*****************************************************************************/
37 * instantiate a request-key authorisation record
39 static int request_key_auth_instantiate(struct key *key,
40 const void *data,
41 size_t datalen)
43 struct request_key_auth *rka, *irka;
44 struct key *instkey;
45 int ret;
47 ret = -ENOMEM;
48 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
49 if (rka) {
50 /* see if the calling process is already servicing the key
51 * request of another process */
52 instkey = key_get_instantiation_authkey(0);
53 if (!IS_ERR(instkey)) {
54 /* it is - use that instantiation context here too */
55 irka = instkey->payload.data;
56 rka->context = irka->context;
57 rka->pid = irka->pid;
58 key_put(instkey);
60 else {
61 /* it isn't - use this process as the context */
62 rka->context = current;
63 rka->pid = current->pid;
66 rka->target_key = key_get((struct key *) data);
67 key->payload.data = rka;
68 ret = 0;
71 return ret;
73 } /* end request_key_auth_instantiate() */
75 /*****************************************************************************/
79 static void request_key_auth_describe(const struct key *key,
80 struct seq_file *m)
82 struct request_key_auth *rka = key->payload.data;
84 seq_puts(m, "key:");
85 seq_puts(m, key->description);
86 seq_printf(m, " pid:%d", rka->pid);
88 } /* end request_key_auth_describe() */
90 /*****************************************************************************/
92 * destroy an instantiation authorisation token key
94 static void request_key_auth_destroy(struct key *key)
96 struct request_key_auth *rka = key->payload.data;
98 kenter("{%d}", key->serial);
100 key_put(rka->target_key);
101 kfree(rka);
103 } /* end request_key_auth_destroy() */
105 /*****************************************************************************/
107 * create a session keyring to be for the invokation of /sbin/request-key and
108 * stick an authorisation token in it
110 struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
112 struct key *keyring, *rkakey = NULL;
113 char desc[20];
114 int ret;
116 kenter("%d,", target->serial);
118 /* allocate a new session keyring */
119 sprintf(desc, "_req.%u", target->serial);
121 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
122 if (IS_ERR(keyring)) {
123 kleave("= %ld", PTR_ERR(keyring));
124 return keyring;
127 /* allocate the auth key */
128 sprintf(desc, "%x", target->serial);
130 rkakey = key_alloc(&key_type_request_key_auth, desc,
131 current->fsuid, current->fsgid,
132 KEY_POS_VIEW | KEY_USR_VIEW, 1);
133 if (IS_ERR(rkakey)) {
134 key_put(keyring);
135 kleave("= %ld", PTR_ERR(rkakey));
136 return rkakey;
139 /* construct and attach to the keyring */
140 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
141 if (ret < 0) {
142 key_revoke(rkakey);
143 key_put(rkakey);
144 key_put(keyring);
145 kleave("= %d", ret);
146 return ERR_PTR(ret);
149 *_rkakey = rkakey;
150 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
151 return keyring;
153 } /* end request_key_auth_new() */
155 /*****************************************************************************/
157 * get the authorisation key for instantiation of a specific key if attached to
158 * the current process's keyrings
159 * - this key is inserted into a keyring and that is set as /sbin/request-key's
160 * session keyring
161 * - a target_id of zero specifies any valid token
163 struct key *key_get_instantiation_authkey(key_serial_t target_id)
165 struct task_struct *tsk = current;
166 struct key *instkey;
168 /* we must have our own personal session keyring */
169 if (!tsk->signal->session_keyring)
170 return ERR_PTR(-EACCES);
172 /* and it must contain a suitable request authorisation key
173 * - lock RCU against session keyring changing
175 rcu_read_lock();
177 instkey = keyring_search_instkey(
178 rcu_dereference(tsk->signal->session_keyring), target_id);
180 rcu_read_unlock();
181 return instkey;
183 } /* end key_get_instantiation_authkey() */