}
}
+ bool root_squash_in_caps() const {
+ for (const MDSCapGrant &g : grants) {
+ if (g.match.root_squash) {
+ return true;
+ }
+ }
+ return false;
+ }
+
friend std::ostream &operator<<(std::ostream &out, const MDSAuthCaps &cap);
private:
std::vector<MDSCapGrant> grants;
break;
}
+ if (session->auth_caps.root_squash_in_caps() && !client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK)) {
+ CachedStackStringStream css;
+ *css << "client lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK needed to enforce 'root_squash' MDS auth caps";
+ send_reject_message(css->strv());
+ mds->clog->warn() << "client session (" << session->info.inst
+ << ") lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK "
+ << " needed to enforce 'root_squash' MDS auth caps";
+ session->clear();
+ break;
+
+ }
// Special case for the 'root' metadata path; validate that the claimed
// root is actually within the caps of the session
if (auto it = client_metadata.find("root"); it != client_metadata.end()) {
*css << "missing required features '" << missing_features << "'";
error_str = css->strv();
}
+ if (session->auth_caps.root_squash_in_caps() &&
+ !session->info.client_metadata.features.test(CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK)) {
+ CachedStackStringStream css;
+ *css << "client lacks CEPHFS_FEATURE_MDS_AUTH_CAPS_CHECK needed to enforce 'root_squash' MDS auth caps";
+ error_str = css->strv();
+ }
}
if (!error_str.empty()) {