| 1092 | } |
| 1093 | |
| 1094 | int Session::check_access(std::string_view fs_name, CInode *in, unsigned mask, |
| 1095 | int caller_uid, int caller_gid, |
| 1096 | const vector<uint64_t> *caller_gid_list, |
| 1097 | int new_uid, int new_gid) |
| 1098 | { |
| 1099 | dout(20) << __func__ << ": " << *in |
| 1100 | << " caller_uid=" << caller_uid |
| 1101 | << " caller_gid=" << caller_gid |
| 1102 | << " caller_gid_list=" << *caller_gid_list |
| 1103 | << dendl; |
| 1104 | |
| 1105 | string path; |
| 1106 | if (!in->is_base()) { |
| 1107 | auto* dn = in->get_projected_parent_dn(); |
| 1108 | auto* pdiri = dn->get_dir()->get_inode(); |
| 1109 | if (pdiri) { |
| 1110 | if (pdiri->is_stray()) { |
| 1111 | path = in->get_projected_inode()->stray_prior_path; |
| 1112 | } else if (!pdiri->is_base()) { |
| 1113 | /* is the pdiri in the stray (is this inode in a snapshotted deleted directory?) */ |
| 1114 | auto* gpdiri = pdiri->get_projected_parent_dn()->get_dir()->get_inode(); |
| 1115 | /* stray_prior_path will not necessarily be part of the inode because |
| 1116 | * it's set on unlink but that happens after the snapshot, naturally. |
| 1117 | * We need to construct it manually. |
| 1118 | */ |
| 1119 | if (gpdiri->is_stray()) { |
| 1120 | /* just check access on the parent dir */ |
| 1121 | path = pdiri->get_projected_inode()->stray_prior_path; |
| 1122 | } |
| 1123 | } |
| 1124 | } |
| 1125 | } |
| 1126 | |
| 1127 | string trimmed_path = ""; |
| 1128 | if (!path.empty()) { |
| 1129 | dout(20) << __func__ << " stray_prior_path " << path << dendl; |
| 1130 | } else { |
| 1131 | in->make_path_string(path, true); |
| 1132 | /* Log only 10 final components fo the path to since logging entire |
| 1133 | * path is not useful and also reduces readability. */ |
| 1134 | dout(20) << __func__ << " path " << get_trimmed_path_str(path) << dendl; |
| 1135 | } |
| 1136 | if (path.length()) |
| 1137 | path = path.substr(1); // drop leading / |
| 1138 | |
| 1139 | const auto& inode = in->get_inode(); |
| 1140 | if (in->is_dir() && |
| 1141 | inode->has_layout() && |
| 1142 | inode->layout.pool_ns.length() && |
| 1143 | !connection->has_feature(CEPH_FEATURE_FS_FILE_LAYOUT_V2)) { |
| 1144 | dout(10) << __func__ << " client doesn't support FS_FILE_LAYOUT_V2" << dendl; |
| 1145 | return -EIO; |
| 1146 | } |
| 1147 | |
| 1148 | if (!auth_caps.is_capable(fs_name, path, inode->uid, inode->gid, inode->mode, |
| 1149 | caller_uid, caller_gid, caller_gid_list, mask, |
| 1150 | new_uid, new_gid, info.inst.addr, trimmed_path)) { |
| 1151 | return -EACCES; |
nothing calls this directly
no test coverage detected