From 2c576e5c2c485bd6ec4a9289ea282f316bc37ab6 Mon Sep 17 00:00:00 2001 From: Christopher Hoffman Date: Fri, 19 Jul 2024 14:44:04 +0000 Subject: [PATCH] client: Implement status for fscrypt key status Fixes: https://tracker.ceph.com/issues/64130 Signed-off-by: Christopher Hoffman --- src/client/Client.cc | 31 +++++++++++++++++++++++++++++++ src/client/Client.h | 2 ++ src/client/fuse_ll.cc | 24 +----------------------- src/libcephfs.cc | 9 +++++++++ 4 files changed, 43 insertions(+), 23 deletions(-) diff --git a/src/client/Client.cc b/src/client/Client.cc index a395302fdb7..3fb9b975354 100644 --- a/src/client/Client.cc +++ b/src/client/Client.cc @@ -18295,6 +18295,37 @@ int Client::ll_set_fscrypt_policy_v2(Inode *in, const struct fscrypt_policy_v2& return 0; } +int Client::get_fscrypt_key_status(fscrypt_get_key_status_arg* arg) { + ceph_fscrypt_key_identifier kid; + int r = kid.init(arg->key_spec); + if (r < 0) { + return r; + } + unsigned int status = 0; + unsigned int status_flags = 0; + unsigned int user_count = 0; + + FSCryptKeyHandlerRef kh; + r = fscrypt->get_key_store().find(kid, kh); + + if (!kh){ + status = FSCRYPT_KEY_STATUS_ABSENT; + goto out; + } + + user_count = kh->get_users().size(); + + if (!kh->present) { + status = FSCRYPT_KEY_STATUS_INCOMPLETELY_REMOVED; + } else { + status = FSCRYPT_KEY_STATUS_PRESENT; + } +out: + arg->status = status; + arg->status_flags = status_flags; //TODO: implement this + arg->user_count = user_count; + return 0; +} // called before mount. 0 means infinite void Client::set_session_timeout(unsigned timeout) diff --git a/src/client/Client.h b/src/client/Client.h index e684e7502f8..6e4d8802cd8 100644 --- a/src/client/Client.h +++ b/src/client/Client.h @@ -344,6 +344,8 @@ public: /* fscrypt */ int add_fscrypt_key(const char *key_data, int key_len, ceph_fscrypt_key_identifier *kid, int user = 0); int remove_fscrypt_key(fscrypt_remove_key_arg* kid, int user = 0); + int get_fscrypt_key_status(fscrypt_get_key_status_arg* arg); + int set_fscrypt_policy_v2(int fd, const struct fscrypt_policy_v2& policy); int mds_command( diff --git a/src/client/fuse_ll.cc b/src/client/fuse_ll.cc index f59a24137c4..16c86f6728c 100644 --- a/src/client/fuse_ll.cc +++ b/src/client/fuse_ll.cc @@ -1115,29 +1115,7 @@ static void fuse_ll_ioctl(fuse_req_t req, fuse_ino_t ino, break; } - ceph_fscrypt_key_identifier kid; - int r = kid.init(arg->key_spec); - if (r < 0) { - fuse_reply_err(req, -r); - break; - } - - FSCryptKeyHandlerRef kh; - r = cfuse->client->fscrypt->get_key_store().find(kid, kh); - if (r < 0 && r != -ENOENT) { - fuse_reply_err(req, -r); - break; - } - - bool found = (r == 0 && kh->get_key()); - - generic_dout(0) << __FILE__ << ":" << __LINE__ << ": FS_IOC_GET_ENCRYPTION_KEY_STATUS found=" << found << dendl; - - /* TODO: return correct info */ - arg->status = (found ? FSCRYPT_KEY_STATUS_PRESENT : FSCRYPT_KEY_STATUS_ABSENT); - arg->status_flags = 0;//(found ? 0x1 : 0); /* FIXME */ - //arg->status_flags = (found ? 0x1 : 0); /* FIXME */ - arg->user_count = !!found; /* FIXME */ + int r = cfuse->client->get_fscrypt_key_status(arg); fuse_reply_ioctl(req, 0, arg, sizeof(*arg)); } diff --git a/src/libcephfs.cc b/src/libcephfs.cc index 640ad4cde82..8ad2b9200e8 100644 --- a/src/libcephfs.cc +++ b/src/libcephfs.cc @@ -2515,6 +2515,15 @@ extern "C" int ceph_remove_fscrypt_key(struct ceph_mount_info *cmount, return cmount->get_client()->remove_fscrypt_key(kid, user); } +extern "C" int ceph_get_fscrypt_key_status(struct ceph_mount_info *cmount, + struct fscrypt_get_key_status_arg *arg) +{ + if (!cmount->is_mounted()) + return -CEPHFS_ENOTCONN; + + return cmount->get_client()->get_fscrypt_key_status(arg); +} + extern "C" int ceph_set_fscrypt_policy_v2(struct ceph_mount_info *cmount, int fd, const struct fscrypt_policy_v2 *policy) { -- 2.39.5