return is_admin;
}
+/* We forbid operations from encryption-unaware clients if they try to
+ * manipulate encrypted files/directories.
+ */
+static inline int mdt_check_enc(struct mdt_thread_info *info,
+ struct mdt_object *obj)
+{
+ struct obd_export *exp;
+ struct md_attr ma = { 0 };
+ int rc = 0;
+
+ if (!mdt_info_req(info))
+ /* no req, so cannot tell about client connection flags:
+ * allow access
+ */
+ return 0;
+ exp = mdt_info_req(info)->rq_export;
+ if (exp_connect_encrypt(exp))
+ /* client is encryption aware: fine */
+ return 0;
+
+ ma.ma_need = MA_INODE;
+ mdt_attr_get_complex(info, obj, &ma);
+ if (ma.ma_attr.la_valid & LA_FLAGS &&
+ ma.ma_attr.la_flags & LUSTRE_ENCRYPT_FL)
+ rc = -ENOKEY;
+
+ if (rc)
+ CDEBUG(D_SEC, "%s: operation on encrypted "DFID
+ " from encryption-unaware client %s: %d\n",
+ mdt_obd_name(info->mti_mdt),
+ PFID(lu_object_fid(&obj->mot_obj)),
+ libcfs_nidstr(&exp->exp_connection->c_peer.nid), rc);
+
+ return rc;
+}
+
int mdt_reint_migrate(struct mdt_thread_info *info,
struct mdt_lock_handle *unused);
int mdt_dir_layout_update(struct mdt_thread_info *info);
if (IS_ERR(o))
RETURN(rc = PTR_ERR(o));
+ rc = mdt_check_enc(info, o);
+ if (rc)
+ GOTO(out, rc);
+
if (unlikely(mdt_object_remote(o))) {
/* the child object was created on remote server */
struct mdt_body *repbody;
GOTO(out, rc = -ENOENT);
}
+ /* do not check enc for directory: always allow open */
+ if (!S_ISDIR(lu_object_attr(&o->mot_obj))) {
+ rc = mdt_check_enc(info, o);
+ if (rc)
+ GOTO(out, rc);
+ }
+
mdt_set_disposition(info, rep, (DISP_IT_EXECD | DISP_LOOKUP_EXECD));
mdt_prep_ma_buf_from_rep(info, o, ma);
if (IS_ERR(o))
RETURN(rc = PTR_ERR(o));
+ rc = mdt_check_enc(info, o);
+ if (rc)
+ GOTO(out, rc);
+
if (mdt_object_remote(o)) {
/* Something is wrong here, the object is on another MDS! */
CERROR("%s: "DFID" isn't on this server!: rc = %d\n",
GOTO(out, result);
}
+ result = mdt_check_enc(info, parent);
+ if (result)
+ GOTO(out_parent, result);
+
fid_zero(child_fid);
result = -ENOENT;
lock_mode = mdt_open_lock_mode(info, parent, &rr->rr_name, open_flags);
if (!mdt_object_exists(parent))
GOTO(put_parent, rc = -ENOENT);
+ rc = mdt_check_enc(info, parent);
+ if (rc)
+ GOTO(put_parent, rc);
+
/*
* LU-10235: check if name exists locklessly first to avoid massive
* lock recalls on existing directories.
if (rc)
GOTO(put_parent, rc);
+ rc = mdt_check_enc(info, mp);
+ if (rc)
+ GOTO(put_parent, rc);
+
/* step 2: find source */
ms = mdt_object_find(info->mti_env, info->mti_mdt, rr->rr_fid1);
if (IS_ERR(ms))
if (!S_ISDIR(lu_object_attr(&pobj->mot_obj)))
GOTO(put_parent, rc = -ENOTDIR);
+ rc = mdt_check_enc(info, pobj);
+ if (rc)
+ GOTO(put_parent, rc);
+
rc = mdt_stripe_get(info, pobj, ma, XATTR_NAME_LMV);
if (rc)
GOTO(put_parent, rc);
if (IS_ERR(msrcdir))
RETURN(PTR_ERR(msrcdir));
+ rc = mdt_check_enc(info, msrcdir);
+ if (rc)
+ GOTO(out_put_srcdir, rc);
+
OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_RENAME3, 5);
if (lu_fid_eq(rr->rr_fid1, rr->rr_fid2)) {
GOTO(out_put_srcdir, rc = PTR_ERR(mtgtdir));
}
+ rc = mdt_check_enc(info, mtgtdir);
+ if (rc)
+ GOTO(out_put_tgtdir, rc);
+
/*
* Note: do not enqueue rename lock for replay request, because
* if other MDT holds rename lock, but being blocked to wait for
test_54() {
local testdir=$DIR/$tdir/$ID0
+ local testdir2=$DIR2/$tdir/$ID0
local testfile=$testdir/$tfile
local testfile2=$testdir/${tfile}withveryverylongnametoexercisecode
local tmpfile=$TMP/${tfile}.tmp
$RUNAS hexdump -C ${scrambledfiles[1]} &&
error "reading ${scrambledfiles[1]} should fail without key"
+ # server local client incompatible with SSK keys installed
+ if [ "$SHARED_KEY" != true ]; then
+ mount_mds_client
+ do_facet $SINGLEMDS touch $DIR2/$tdir/newfile
+ mdsscrambledfile=$(do_facet $SINGLEMDS find $testdir2/ \
+ -maxdepth 1 -type f | head -n1)
+ [ -n "$mdsscrambledfile" ] || error "could not find file"
+ do_facet $SINGLEMDS cat "$mdsscrambledfile" &&
+ error "reading $mdsscrambledfile should fail on MDS"
+ do_facet $SINGLEMDS "echo aaa >> \"$mdsscrambledfile\"" &&
+ error "writing $mdsscrambledfile should fail on MDS"
+ do_facet $SINGLEMDS $MULTIOP $testdir2/fileA m &&
+ error "creating $testdir2/fileA should fail on MDS"
+ do_facet $SINGLEMDS mkdir $testdir2/dirA &&
+ error "mkdir $testdir2/dirA should fail on MDS"
+ do_facet $SINGLEMDS ln -s $DIR2/$tdir/newfile $testdir2/sl1 &&
+ error "ln -s $testdir2/sl1 should fail on MDS"
+ do_facet $SINGLEMDS ln $DIR2/$tdir/newfile $testdir2/hl1 &&
+ error "ln $testdir2/hl1 should fail on MDS"
+ do_facet $SINGLEMDS mv "$mdsscrambledfile" $testdir2/fB &&
+ error "mv $mdsscrambledfile should fail on MDS"
+ do_facet $SINGLEMDS mrename "$mdsscrambledfile" $testdir2/fB &&
+ error "mrename $mdsscrambledfile should fail on MDS"
+ do_facet $SINGLEMDS rm -f $DIR2/$tdir/newfile
+ umount_mds_client
+ fi
+
echo mypass | $RUNAS fscrypt unlock --verbose $testdir ||
error "fscrypt unlock $testdir failed (2)"