From 958addc0c9329cf0d3f72b909ab90b40bdfa0ea3 Mon Sep 17 00:00:00 2001 From: Josh Durgin Date: Sat, 29 Dec 2012 20:26:57 -0800 Subject: [PATCH] rbd: open (source) image as read-only This allows users without write access to copy, export and list information about an image. Signed-off-by: Josh Durgin --- qa/workunits/rbd/permissions.sh | 121 ++++++++++++++++++++++++++++++++ src/rbd.cc | 27 ++++--- 2 files changed, 138 insertions(+), 10 deletions(-) create mode 100755 qa/workunits/rbd/permissions.sh diff --git a/qa/workunits/rbd/permissions.sh b/qa/workunits/rbd/permissions.sh new file mode 100755 index 0000000000000..40428df38e3e5 --- /dev/null +++ b/qa/workunits/rbd/permissions.sh @@ -0,0 +1,121 @@ +#!/bin/bash -ex + +create_pools() { + ceph osd pool create images 100 + ceph osd pool create volumes 100 +} + +delete_pools() { + (ceph osd pool delete images || true) >/dev/null 2>&1 + (ceph osd pool delete volumes || true) >/dev/null 2>&1 + +} + +recreate_pools() { + create_pools + delete_pools +} + +delete_uers() { + (ceph auth del client.volumes || true) >/dev/null 2>&1 + (ceph auth del client.images || true) >/dev/null 2>&1 +} + +create_users() { + ceph auth get-or-create client.volumes mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow r class-read pool images, allow rwx pool volumes' >> $KEYRING + ceph auth get-or-create client.images mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool images' >> $KEYRING +} + +test_images_access() { + rbd -k $KEYRING --id images create --format 2 -s 1 images/foo + rbd -k $KEYRING --id images snap create images/foo@snap + rbd -k $KEYRING --id images snap protect images/foo@snap + rbd -k $KEYRING --id images snap unprotect images/foo@snap + rbd -k $KEYRING --id images snap protect images/foo@snap + rbd -k $KEYRING --id images export images/foo@snap - >/dev/null + ! rbd -k $KEYRING --id images snap rm images/foo@snap + + rbd -k $KEYRING --id volumes clone images/foo@snap volumes/child + ! rbd -k $KEYRING --id images snap unprotect images/foo@snap + ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap + ! rbd -k $KEYRING --id images flatten volumes/child + rbd -k $KEYRING --id volumes flatten volumes/child + ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap + rbd -k $KEYRING --id images snap unprotect images/foo@snap + + ! rbd -k $KEYRING --id images rm images/foo + rbd -k $KEYRING --id images snap rm images/foo@snap + rbd -k $KEYRING --id images rm images/foo + rbd -k $KEYRING --id volumes rm volumes/child +} + +test_volumes_access() { + rbd -k $KEYRING --id images create --format 2 -s 1 images/foo + rbd -k $KEYRING --id images snap create images/foo@snap + rbd -k $KEYRING --id images snap protect images/foo@snap + + # commands that work with read-only access + rbd -k $KEYRING --id volumes info images/foo@snap + rbd -k $KEYRING --id volumes snap ls images/foo + rbd -k $KEYRING --id volumes export images/foo - >/dev/null + rbd -k $KEYRING --id volumes cp images/foo volumes/foo_copy + rbd -k $KEYRING --id volumes rm volumes/foo_copy + rbd -k $KEYRING --id volumes children images/foo@snap + rbd -k $KEYRING --id volumes lock list images/foo + + # commands that fail with read-only access + ! rbd -k $KEYRING --id volumes resize -s 2 images/foo + ! rbd -k $KEYRING --id volumes snap create images/foo@2 + ! rbd -k $KEYRING --id volumes snap rollback images/foo@snap + ! rbd -k $KEYRING --id volumes snap remove images/foo@snap + ! rbd -k $KEYRING --id volumes snap purge images/foo + ! rbd -k $KEYRING --id volumes snap unprotect images/foo@snap + ! rbd -k $KEYRING --id volumes flatten images/foo + ! rbd -k $KEYRING --id volumes lock add images/foo test + ! rbd -k $KEYRING --id volumes lock remove images/foo test locker + ! rbd -k $KEYRING --id volumes ls rbd + + # create clone and snapshot + rbd -k $KEYRING --id volumes clone images/foo@snap volumes/child + rbd -k $KEYRING --id volumes snap create volumes/child@snap1 + rbd -k $KEYRING --id volumes snap protect volumes/child@snap1 + rbd -k $KEYRING --id volumes snap create volumes/child@snap2 + + # make sure original snapshot stays protected + ! rbd -k $KEYRING --id images snap unprotect images/foo@snap + rbd -k $KEYRING --id volumes flatten volumes/child + ! rbd -k $KEYRING --id images snap unprotect images/foo@snap + rbd -k $KEYRING --id volumes snap rm volumes/child@snap2 + ! rbd -k $KEYRING --id images snap unprotect images/foo@snap + ! rbd -k $KEYRING --id volumes snap rm volumes/child@snap2 + rbd -k $KEYRING --id volumes snap unprotect volumes/child@snap1 + ! rbd -k $KEYRING --id images snap unprotect images/foo@snap + + # clean up + rbd -k $KEYRING --id volumes snap rm volumes/child@snap1 + rbd -k $KEYRING --id images snap unprotect images/foo@snap + rbd -k $KEYRING --id images snap rm images/foo@snap + rbd -k $KEYRING --id images rm images/foo + rbd -k $KEYRING --id volumes rm volumes/child +} + +cleanup() { + rm -f $KEYRING +} +KEYRING=$(mktemp) +trap cleanup EXIT ERR HUP INT QUIT + +delete_users +create_users + +recreate_pools +test_images_access + +recreate_pools +test_volumes_access + +delete_pools +delete_users + +echo OK +exit 0 diff --git a/src/rbd.cc b/src/rbd.cc index 2b098b3d983ec..2a13706f18ed5 100644 --- a/src/rbd.cc +++ b/src/rbd.cc @@ -200,7 +200,7 @@ static int do_list(librbd::RBD &rbd, librados::IoCtx& io_ctx, bool lflag) librbd::image_info_t info; librbd::Image im; - r = rbd.open(io_ctx, im, i->c_str()); + r = rbd.open_read_only(io_ctx, im, i->c_str(), NULL); // image might disappear between rbd.list() and rbd.open(); ignore // that, warn about other possible errors (EPERM, say, for opening // an old-format image, because you need execute permission for the @@ -1864,16 +1864,23 @@ if (!set_conf_param(v, p1, p2, p3)) { \ } if (imgname && talk_to_cluster && - (opt_cmd == OPT_RESIZE || opt_cmd == OPT_INFO || - opt_cmd == OPT_SNAP_LIST || opt_cmd == OPT_SNAP_CREATE || + (opt_cmd == OPT_RESIZE || opt_cmd == OPT_SNAP_CREATE || opt_cmd == OPT_SNAP_ROLLBACK || opt_cmd == OPT_SNAP_REMOVE || - opt_cmd == OPT_SNAP_PURGE || opt_cmd == OPT_EXPORT || - opt_cmd == OPT_SNAP_PROTECT || opt_cmd == OPT_SNAP_UNPROTECT || - opt_cmd == OPT_WATCH || opt_cmd == OPT_COPY || - opt_cmd == OPT_FLATTEN || opt_cmd == OPT_CHILDREN || - opt_cmd == OPT_LOCK_LIST || opt_cmd == OPT_LOCK_ADD || - opt_cmd == OPT_LOCK_REMOVE || opt_cmd == OPT_BENCH_WRITE)) { - r = rbd.open(io_ctx, image, imgname); + opt_cmd == OPT_SNAP_PURGE || opt_cmd == OPT_SNAP_PROTECT || + opt_cmd == OPT_SNAP_UNPROTECT || opt_cmd == OPT_WATCH || + opt_cmd == OPT_FLATTEN || opt_cmd == OPT_LOCK_ADD || + opt_cmd == OPT_LOCK_REMOVE || opt_cmd == OPT_BENCH_WRITE || + opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST || + opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY || + opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST)) { + + if (opt_cmd == OPT_INFO || opt_cmd == OPT_SNAP_LIST || + opt_cmd == OPT_EXPORT || opt_cmd == OPT_COPY || + opt_cmd == OPT_CHILDREN || opt_cmd == OPT_LOCK_LIST) { + r = rbd.open_read_only(io_ctx, image, imgname, NULL); + } else { + r = rbd.open(io_ctx, image, imgname); + } if (r < 0) { cerr << "rbd: error opening image " << imgname << ": " << cpp_strerror(-r) << std::endl; -- 2.39.5