Linux v2.6.13-rc3
[pohmelfs.git] / security / keys / request_key_auth.c
blobf22264632229ca79108a1e232461ecda378cc1e8
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.
12 #include <linux/module.h>
13 #include <linux/sched.h>
14 #include <linux/err.h>
15 #include <linux/seq_file.h>
16 #include "internal.h"
18 static int request_key_auth_instantiate(struct key *, const void *, size_t);
19 static void request_key_auth_describe(const struct key *, struct seq_file *);
20 static void request_key_auth_destroy(struct key *);
23 * the request-key authorisation key type definition
25 struct key_type key_type_request_key_auth = {
26 .name = ".request_key_auth",
27 .def_datalen = sizeof(struct request_key_auth),
28 .instantiate = request_key_auth_instantiate,
29 .describe = request_key_auth_describe,
30 .destroy = request_key_auth_destroy,
33 /*****************************************************************************/
35 * instantiate a request-key authorisation record
37 static int request_key_auth_instantiate(struct key *key,
38 const void *data,
39 size_t datalen)
41 struct request_key_auth *rka, *irka;
42 struct key *instkey;
43 int ret;
45 ret = -ENOMEM;
46 rka = kmalloc(sizeof(*rka), GFP_KERNEL);
47 if (rka) {
48 /* see if the calling process is already servicing the key
49 * request of another process */
50 instkey = key_get_instantiation_authkey(0);
51 if (!IS_ERR(instkey)) {
52 /* it is - use that instantiation context here too */
53 irka = instkey->payload.data;
54 rka->context = irka->context;
55 rka->pid = irka->pid;
56 key_put(instkey);
58 else {
59 /* it isn't - use this process as the context */
60 rka->context = current;
61 rka->pid = current->pid;
64 rka->target_key = key_get((struct key *) data);
65 key->payload.data = rka;
66 ret = 0;
69 return ret;
71 } /* end request_key_auth_instantiate() */
73 /*****************************************************************************/
77 static void request_key_auth_describe(const struct key *key,
78 struct seq_file *m)
80 struct request_key_auth *rka = key->payload.data;
82 seq_puts(m, "key:");
83 seq_puts(m, key->description);
84 seq_printf(m, " pid:%d", rka->pid);
86 } /* end request_key_auth_describe() */
88 /*****************************************************************************/
90 * destroy an instantiation authorisation token key
92 static void request_key_auth_destroy(struct key *key)
94 struct request_key_auth *rka = key->payload.data;
96 kenter("{%d}", key->serial);
98 key_put(rka->target_key);
100 } /* end request_key_auth_destroy() */
102 /*****************************************************************************/
104 * create a session keyring to be for the invokation of /sbin/request-key and
105 * stick an authorisation token in it
107 struct key *request_key_auth_new(struct key *target, struct key **_rkakey)
109 struct key *keyring, *rkakey = NULL;
110 char desc[20];
111 int ret;
113 kenter("%d,", target->serial);
115 /* allocate a new session keyring */
116 sprintf(desc, "_req.%u", target->serial);
118 keyring = keyring_alloc(desc, current->fsuid, current->fsgid, 1, NULL);
119 if (IS_ERR(keyring)) {
120 kleave("= %ld", PTR_ERR(keyring));
121 return keyring;
124 /* allocate the auth key */
125 sprintf(desc, "%x", target->serial);
127 rkakey = key_alloc(&key_type_request_key_auth, desc,
128 current->fsuid, current->fsgid,
129 KEY_USR_VIEW, 1);
130 if (IS_ERR(rkakey)) {
131 key_put(keyring);
132 kleave("= %ld", PTR_ERR(rkakey));
133 return rkakey;
136 /* construct and attach to the keyring */
137 ret = key_instantiate_and_link(rkakey, target, 0, keyring, NULL);
138 if (ret < 0) {
139 key_revoke(rkakey);
140 key_put(rkakey);
141 key_put(keyring);
142 kleave("= %d", ret);
143 return ERR_PTR(ret);
146 *_rkakey = rkakey;
147 kleave(" = {%d} ({%d})", keyring->serial, rkakey->serial);
148 return keyring;
150 } /* end request_key_auth_new() */
152 /*****************************************************************************/
154 * get the authorisation key for instantiation of a specific key if attached to
155 * the current process's keyrings
156 * - this key is inserted into a keyring and that is set as /sbin/request-key's
157 * session keyring
158 * - a target_id of zero specifies any valid token
160 struct key *key_get_instantiation_authkey(key_serial_t target_id)
162 struct task_struct *tsk = current;
163 struct key *instkey;
165 /* we must have our own personal session keyring */
166 if (!tsk->signal->session_keyring)
167 return ERR_PTR(-EACCES);
169 /* and it must contain a suitable request authorisation key
170 * - lock RCU against session keyring changing
172 rcu_read_lock();
174 instkey = keyring_search_instkey(
175 rcu_dereference(tsk->signal->session_keyring), target_id);
177 rcu_read_unlock();
178 return instkey;
180 } /* end key_get_instantiation_authkey() */