/* process root_squash here. */
mdt_root_squash(info, peernid);
+ if (ucred->uc_fsuid) {
+ if (!cap_isclear(ucred->uc_cap))
+ CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
+ mdt_obd_name(mdt),
+#ifdef CAP_FOR_EACH_U32
+ ucred->uc_cap.cap[0] |
+ ((u64)ucred->uc_cap.cap[1] << 32),
+#else
+ ucred->uc_cap.val,
+#endif
+ libcfs_nid2str(mdt_info_req(info)->rq_peer.nid));
+ ucred->uc_cap = cap_intersect(ucred->uc_cap,
+ mdt->mdt_enable_cap_mask);
+ }
ucred->uc_valid = UCRED_NEW;
ucred_set_jobid(info, ucred);
ucred_set_nid(info, ucred);
/* process root_squash here. */
mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
+ if (uc->uc_fsuid) {
+ if (!cap_isclear(uc->uc_cap))
+ CDEBUG(D_SEC, "%s: drop capabilities %llx for NID %s\n",
+ mdt_obd_name(mdt),
+#ifdef CAP_FOR_EACH_U32
+ uc->uc_cap.cap[0] | ((u64)uc->uc_cap.cap[1]<<32),
+#else
+ uc->uc_cap.val,
+#endif
+ libcfs_nid2str(mdt_info_req(info)->rq_peer.nid));
+ uc->uc_cap = cap_intersect(uc->uc_cap,mdt->mdt_enable_cap_mask);
+ }
uc->uc_valid = UCRED_OLD;
ucred_set_jobid(info, uc);
ucred_set_nid(info, uc);
}
LPROC_SEQ_FOPS(mdt_nosquash_nids);
+static ssize_t enable_cap_mask_show(struct kobject *kobj,
+ struct attribute *attr, char *buf)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ u64 cap;
+
+ BUILD_BUG_ON(_KERNEL_CAP_T_SIZE != sizeof(u64));
+
+#ifdef CAP_FOR_EACH_U32 /* kernels before v6.2-13111-gf122a08b197d */
+ cap = ((u64)mdt->mdt_enable_cap_mask.cap[1] << 32) |
+ mdt->mdt_enable_cap_mask.cap[0];
+#else
+ cap = mdt->mdt_enable_cap_mask.val;
+#endif
+ return scnprintf(buf, PAGE_SIZE, "%#0llx\n", cap);
+}
+
+static ssize_t enable_cap_mask_store(struct kobject *kobj,
+ struct attribute *attr,
+ const char *buffer, size_t count)
+{
+ struct obd_device *obd = container_of(kobj, struct obd_device,
+ obd_kset.kobj);
+ struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
+ unsigned long long val;
+ int rc;
+
+ rc = kstrtoull(buffer, 0, &val);
+ if (rc)
+ /* should also accept symbolic names via cfs_str2mask() */
+ return rc;
+
+#ifdef CAP_FOR_EACH_U32
+ mdt->mdt_enable_cap_mask.cap[0] = val &
+ (CAP_FS_MASK_B0 | CAP_TO_MASK(CAP_SYS_RESOURCE) |
+ CAP_TO_MASK(CAP_LINUX_IMMUTABLE));
+ mdt->mdt_enable_cap_mask.cap[1] = (val >> 32) & CAP_FS_MASK_B1;
+#else
+ mdt->mdt_enable_cap_mask.val = val &
+ (CAP_FS_MASK | BIT_ULL(CAP_SYS_RESOURCE) |
+ BIT_ULL(CAP_LINUX_IMMUTABLE));
+#endif
+
+ return count;
+}
+LUSTRE_RW_ATTR(enable_cap_mask);
+
static ssize_t enable_remote_dir_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
&lustre_attr_identity_upcall.attr,
&lustre_attr_identity_flush.attr,
&lustre_attr_evict_tgt_nids.attr,
+ &lustre_attr_enable_cap_mask.attr,
&lustre_attr_enable_remote_dir.attr,
&lustre_attr_enable_remote_dir_gid.attr,
&lustre_attr_enable_chprojid_gid.attr,
skip "Need MDS version at least 2.13.53"
mkdir $DIR/$tdir || error "mkdir $tdir"
+ local mdts=$(comma_list $(mdts_nodes))
+ local cap_param=mdt.*.enable_cap_mask
+
+ old_cap=($(do_nodes $mdts $LCTL get_param -n $cap_param 2>/dev/null))
+ if [[ -n "$old_cap" ]]; then
+ do_nodes $mdts $LCTL set_param $cap_param=0xf
+ stack_trap "do_nodes $mdts $LCTL set_param $cap_param=$old_cap"
+ fi
touch $DIR/$tdir/$tfile || error "touch $tfile"
cp $(which chown) $DIR/$tdir || error "cp chown"