aboutsummaryrefslogtreecommitdiffstats
path: root/net/ceph/ceph_common.c
diff options
context:
space:
mode:
authorTommi Virtanen <tommi.virtanen@dreamhost.com>2011-03-25 19:40:48 -0400
committerSage Weil <sage@newdream.net>2011-03-29 15:11:19 -0400
commite2c3d29b4295c3eec18294bc34f0c99a7b9ae413 (patch)
tree29fbffeeed7e2774a4f87883ae01798079d85ed2 /net/ceph/ceph_common.c
parent8323c3aa74cd92465350294567142d12ffdcc963 (diff)
libceph: Get secret from the kernel keys api when mounting with key=NAME.
Signed-off-by: Tommi Virtanen <tommi.virtanen@dreamhost.com> Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'net/ceph/ceph_common.c')
-rw-r--r--net/ceph/ceph_common.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 02e084f29d24..c92bc8d50597 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -5,6 +5,8 @@
5#include <linux/fs.h> 5#include <linux/fs.h>
6#include <linux/inet.h> 6#include <linux/inet.h>
7#include <linux/in6.h> 7#include <linux/in6.h>
8#include <linux/key.h>
9#include <keys/user-type.h>
8#include <linux/module.h> 10#include <linux/module.h>
9#include <linux/mount.h> 11#include <linux/mount.h>
10#include <linux/parser.h> 12#include <linux/parser.h>
@@ -197,6 +199,7 @@ enum {
197 Opt_fsid, 199 Opt_fsid,
198 Opt_name, 200 Opt_name,
199 Opt_secret, 201 Opt_secret,
202 Opt_key,
200 Opt_ip, 203 Opt_ip,
201 Opt_last_string, 204 Opt_last_string,
202 /* string args above */ 205 /* string args above */
@@ -213,6 +216,7 @@ static match_table_t opt_tokens = {
213 {Opt_fsid, "fsid=%s"}, 216 {Opt_fsid, "fsid=%s"},
214 {Opt_name, "name=%s"}, 217 {Opt_name, "name=%s"},
215 {Opt_secret, "secret=%s"}, 218 {Opt_secret, "secret=%s"},
219 {Opt_key, "key=%s"},
216 {Opt_ip, "ip=%s"}, 220 {Opt_ip, "ip=%s"},
217 /* string args above */ 221 /* string args above */
218 {Opt_noshare, "noshare"}, 222 {Opt_noshare, "noshare"},
@@ -232,6 +236,50 @@ void ceph_destroy_options(struct ceph_options *opt)
232} 236}
233EXPORT_SYMBOL(ceph_destroy_options); 237EXPORT_SYMBOL(ceph_destroy_options);
234 238
239/* get secret from key store */
240static int get_secret(struct ceph_crypto_key *dst, const char *name) {
241 struct key *ukey;
242 int key_err;
243 int err = 0;
244 struct user_key_payload *payload;
245 void *p;
246
247 ukey = request_key(&key_type_user, name, NULL);
248 if (!ukey || IS_ERR(ukey)) {
249 /* request_key errors don't map nicely to mount(2)
250 errors; don't even try, but still printk */
251 key_err = PTR_ERR(ukey);
252 switch (key_err) {
253 case -ENOKEY:
254 pr_warning("ceph: Mount failed due to key not found: %s\n", name);
255 break;
256 case -EKEYEXPIRED:
257 pr_warning("ceph: Mount failed due to expired key: %s\n", name);
258 break;
259 case -EKEYREVOKED:
260 pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
261 break;
262 default:
263 pr_warning("ceph: Mount failed due to unknown key error"
264 " %d: %s\n", key_err, name);
265 }
266 err = -EPERM;
267 goto out;
268 }
269
270 payload = ukey->payload.data;
271 p = payload->data;
272 err = ceph_crypto_key_decode(dst, &p, p + payload->datalen);
273 if (err)
274 goto out_key;
275 /* pass through, err is 0 */
276
277out_key:
278 key_put(ukey);
279out:
280 return err;
281}
282
235int ceph_parse_options(struct ceph_options **popt, char *options, 283int ceph_parse_options(struct ceph_options **popt, char *options,
236 const char *dev_name, const char *dev_name_end, 284 const char *dev_name, const char *dev_name_end,
237 int (*parse_extra_token)(char *c, void *private), 285 int (*parse_extra_token)(char *c, void *private),
@@ -328,6 +376,16 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
328 if (err < 0) 376 if (err < 0)
329 goto out; 377 goto out;
330 break; 378 break;
379 case Opt_key:
380 opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
381 if (!opt->key) {
382 err = -ENOMEM;
383 goto out;
384 }
385 err = get_secret(opt->key, argstr[0].from);
386 if (err < 0)
387 goto out;
388 break;
331 389
332 /* misc */ 390 /* misc */
333 case Opt_osdtimeout: 391 case Opt_osdtimeout: