static int mdt_getattr_name(struct tgt_session_info *tsi)
{
struct mdt_thread_info *info = tsi2mdt_info(tsi);
- struct mdt_lock_handle *lhc = &info->mti_lh[MDT_LH_CHILD];
- struct mdt_body *reqbody;
- struct mdt_body *repbody;
- int rc, rc2;
- ENTRY;
+ struct mdt_lock_handle *lhc = &info->mti_lh[MDT_LH_CHILD];
+ struct mdt_body *reqbody;
+ struct mdt_body *repbody;
+ int rc, rc2;
- reqbody = req_capsule_client_get(info->mti_pill, &RMF_MDT_BODY);
- LASSERT(reqbody != NULL);
- repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
- LASSERT(repbody != NULL);
+ ENTRY;
+
+ reqbody = req_capsule_client_get(info->mti_pill, &RMF_MDT_BODY);
+ LASSERT(reqbody != NULL);
+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
+ LASSERT(repbody != NULL);
info->mti_cross_ref = !!(reqbody->mbo_valid & OBD_MD_FLCROSSREF);
repbody->mbo_eadatasize = 0;
repbody->mbo_aclsize = 0;
- rc = mdt_init_ucred_intent_getattr(info, reqbody);
- if (unlikely(rc))
- GOTO(out_shrink, rc);
+ rc = mdt_init_ucred(info, reqbody);
+ if (unlikely(rc))
+ GOTO(out_shrink, rc);
- rc = mdt_getattr_name_lock(info, lhc, MDS_INODELOCK_UPDATE, NULL);
- if (lustre_handle_is_used(&lhc->mlh_reg_lh)) {
- ldlm_lock_decref(&lhc->mlh_reg_lh, lhc->mlh_reg_mode);
- lhc->mlh_reg_lh.cookie = 0;
- }
- mdt_exit_ucred(info);
- EXIT;
+ rc = mdt_getattr_name_lock(info, lhc, MDS_INODELOCK_UPDATE, NULL);
+ if (lustre_handle_is_used(&lhc->mlh_reg_lh)) {
+ ldlm_lock_decref(&lhc->mlh_reg_lh, lhc->mlh_reg_mode);
+ lhc->mlh_reg_lh.cookie = 0;
+ }
+ mdt_exit_ucred(info);
+ EXIT;
out_shrink:
- mdt_client_compatibility(info);
- rc2 = mdt_fix_reply(info);
- if (rc == 0)
- rc = rc2;
+ mdt_client_compatibility(info);
+ rc2 = mdt_fix_reply(info);
+ if (rc == 0)
+ rc = rc2;
mdt_thread_info_fini(info);
return rc;
}
GOTO(out_shrink, rc = -EINVAL);
}
- rc = mdt_init_ucred_intent_getattr(info, reqbody);
+ rc = mdt_init_ucred(info, reqbody);
if (rc)
GOTO(out_shrink, rc);
bool allow_client_chgrp(struct mdt_thread_info *info, struct lu_ucred *uc);
int mdt_check_ucred(struct mdt_thread_info *);
int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *);
-int mdt_init_ucred_intent_getattr(struct mdt_thread_info *, struct mdt_body *);
int mdt_init_ucred_reint(struct mdt_thread_info *);
void mdt_exit_ucred(struct mdt_thread_info *);
int mdt_version_get_check(struct mdt_thread_info *, struct mdt_object *, int);
}
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
- void *buf, bool drop_fs_cap)
+ void *buf)
{
struct ptlrpc_request *req = mdt_info_req(info);
struct mdt_device *mdt = info->mti_mdt;
/* process root_squash here. */
mdt_root_squash(info, peernid);
- /* remove fs privilege for non-root user. */
- if (ucred->uc_fsuid && drop_fs_cap)
- ucred->uc_cap = pud->pud_cap & ~CFS_CAP_FS_MASK;
- else
- ucred->uc_cap = pud->pud_cap;
+ ucred->uc_cap = pud->pud_cap;
ucred->uc_valid = UCRED_NEW;
ucred_set_jobid(info, ucred);
ucred_set_nid(info, ucred);
}
static int old_init_ucred_common(struct mdt_thread_info *info,
- struct lu_nodemap *nodemap,
- bool drop_fs_cap)
+ struct lu_nodemap *nodemap)
{
struct lu_ucred *uc = mdt_ucred(info);
struct mdt_device *mdt = info->mti_mdt;
/* process root_squash here. */
mdt_root_squash(info, mdt_info_req(info)->rq_peer.nid);
- /* remove fs privilege for non-root user. */
- if (uc->uc_fsuid && drop_fs_cap)
- uc->uc_cap &= ~CFS_CAP_FS_MASK;
uc->uc_valid = UCRED_OLD;
ucred_set_jobid(info, uc);
ucred_set_nid(info, uc);
}
static int old_init_ucred(struct mdt_thread_info *info,
- struct mdt_body *body, bool drop_fs_cap)
+ struct mdt_body *body)
{
struct lu_ucred *uc = mdt_ucred(info);
struct lu_nodemap *nodemap;
uc->uc_ginfo = NULL;
uc->uc_cap = body->mbo_capability;
- rc = old_init_ucred_common(info, nodemap, drop_fs_cap);
+ rc = old_init_ucred_common(info, nodemap);
nodemap_putref(nodemap);
RETURN(rc);
uc->uc_o_gid = uc->uc_o_fsgid = uc->uc_gid = uc->uc_fsgid;
uc->uc_ginfo = NULL;
- rc = old_init_ucred_common(info, nodemap, true); /* drop_fs_cap=true */
+ rc = old_init_ucred_common(info, nodemap);
nodemap_putref(nodemap);
RETURN(rc);
}
static inline int __mdt_init_ucred(struct mdt_thread_info *info,
- struct mdt_body *body,
- bool drop_fs_cap)
+ struct mdt_body *body)
{
struct ptlrpc_request *req = mdt_info_req(info);
struct lu_ucred *uc = mdt_ucred(info);
mdt_exit_ucred(info);
if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
- return old_init_ucred(info, body, drop_fs_cap);
+ return old_init_ucred(info, body);
else
- return new_init_ucred(info, BODY_INIT, body, drop_fs_cap);
+ return new_init_ucred(info, BODY_INIT, body);
}
int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body)
{
- return __mdt_init_ucred(info, body, true);
-}
-
-/* LU-6528 when "no_subtree_check" is set for NFS export, nfsd_set_fh_dentry()
- * doesn't set correct fsuid explicitely, but raise capability to allow
- * exportfs_decode_fh() to reconnect disconnected dentry into dcache. So for
- * lookup (i.e. intent_getattr), we should keep FS capability, otherwise it
- * will fail permission check. */
-int mdt_init_ucred_intent_getattr(struct mdt_thread_info *info,
- struct mdt_body *body)
-{
- return __mdt_init_ucred(info, body, false);
+ return __mdt_init_ucred(info, body);
}
int mdt_init_ucred_reint(struct mdt_thread_info *info)
if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
return old_init_ucred_reint(info);
else
- return new_init_ucred(info, REC_INIT, NULL, true);
+ return new_init_ucred(info, REC_INIT, NULL);
}
/* copied from lov/lov_ea.c, just for debugging, will be removed later */
}
run_test 50 "DoM encrypted file"
+test_51() {
+ [ "$MDS1_VERSION" -gt $(version_code 2.13.53) ] ||
+ skip "Need MDS version at least 2.13.53"
+
+ mkdir $DIR/$tdir || error "mkdir $tdir"
+
+ touch $DIR/$tdir/$tfile || error "touch $tfile"
+ cp $(which chown) $DIR/$tdir || error "cp chown"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile &&
+ error "chown $tfile should fail"
+ setcap 'CAP_CHOWN=ep' $DIR/$tdir/chown || error "setcap CAP_CHOWN"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/chown $ID0 $DIR/$tdir/$tfile ||
+ error "chown $tfile"
+ rm $DIR/$tdir/$tfile || error "rm $tfile"
+
+ touch $DIR/$tdir/$tfile || error "touch $tfile"
+ cp $(which touch) $DIR/$tdir || error "cp touch"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile &&
+ error "touch should fail"
+ setcap 'CAP_FOWNER=ep' $DIR/$tdir/touch || error "setcap CAP_FOWNER"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/touch $DIR/$tdir/$tfile ||
+ error "touch $tfile"
+ rm $DIR/$tdir/$tfile || error "rm $tfile"
+
+ local cap
+ for cap in "CAP_DAC_OVERRIDE" "CAP_DAC_READ_SEARCH"; do
+ touch $DIR/$tdir/$tfile || error "touch $tfile"
+ chmod 600 $DIR/$tdir/$tfile || error "chmod $tfile"
+ cp $(which cat) $DIR/$tdir || error "cp cat"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile &&
+ error "cat should fail"
+ setcap $cap=ep $DIR/$tdir/cat || error "setcap $cap"
+ $RUNAS_CMD -u $ID0 $DIR/$tdir/cat $DIR/$tdir/$tfile ||
+ error "cat $tfile"
+ rm $DIR/$tdir/$tfile || error "rm $tfile"
+ done
+}
+run_test 51 "FS capabilities ==============="
+
log "cleanup: ======================================================"
sec_unsetup() {