return (__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32);
}
+static struct upcall_cache *get_cache(struct mdt_thread_info *info)
+{
+ /* If nodemap does not have server_upcall role,
+ * use dedicated INTERNAL upcall cache, unless
+ * Kerberos is enforced, in which case we do not trust the client's
+ * provided supplementary groups.
+ */
+ struct ptlrpc_request *req = mdt_info_req(info);
+
+ if (SPTLRPC_FLVR_MECH(req->rq_flvr.sf_rpc) == SPTLRPC_MECH_GSS_KRB5 ||
+ mdt_ucred(info)->uc_rbac_server_upcall)
+ return info->mti_mdt->mdt_identity_cache;
+
+ return info->mti_mdt->mdt_identity_cache_int;
+}
+
void mdt_exit_ucred(struct mdt_thread_info *info)
{
struct lu_ucred *uc = mdt_ucred(info);
- struct mdt_device *mdt = info->mti_mdt;
LASSERT(uc != NULL);
if (uc->uc_valid != UCRED_INIT) {
uc->uc_ginfo = NULL;
}
if (uc->uc_identity) {
- mdt_identity_put(mdt->mdt_identity_cache,
- uc->uc_identity);
+ mdt_identity_put(get_cache(info), uc->uc_identity);
uc->uc_identity = NULL;
}
uc->uc_valid = UCRED_INIT;
uc->uc_rbac_byfid_ops = !!(rbac & NODEMAP_RBAC_BYFID_OPS);
uc->uc_rbac_chlg_ops = !!(rbac & NODEMAP_RBAC_CHLG_OPS);
uc->uc_rbac_fscrypt_admin = !!(rbac & NODEMAP_RBAC_FSCRYPT_ADMIN);
+ uc->uc_rbac_server_upcall = !!(rbac & NODEMAP_RBAC_SERVER_UPCALL);
}
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
/* deny access before we get identity ref */
GOTO(out, rc = -EACCES);
+ ucred_set_rbac_roles(info, ucred);
+
/* Fetch external identity info, if enabled */
- if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
- identity = mdt_identity_get(mdt->mdt_identity_cache,
+ if (!is_identity_get_disabled(get_cache(info))) {
+ identity = mdt_identity_get(get_cache(info),
pud->pud_uid, info);
if (IS_ERR(identity)) {
if (unlikely(PTR_ERR(identity) == -EREMCHG ||
ucred_set_jobid(info, ucred);
ucred_set_nid(info, ucred);
ucred_set_audit_enabled(info, ucred);
- ucred_set_rbac_roles(info, ucred);
ucred->uc_valid = UCRED_NEW;
ucred->uc_ginfo = NULL;
}
if (ucred->uc_identity) {
- mdt_identity_put(mdt->mdt_identity_cache,
- ucred->uc_identity);
+ mdt_identity_put(get_cache(info), ucred->uc_identity);
ucred->uc_identity = NULL;
}
}
/* deny access before we get identity ref */
RETURN(-EACCES);
- if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
- identity = mdt_identity_get(mdt->mdt_identity_cache,
+ ucred_set_rbac_roles(info, uc);
+
+ if (!is_identity_get_disabled(get_cache(info))) {
+ identity = mdt_identity_get(get_cache(info),
uc->uc_fsuid, info);
if (IS_ERR(identity)) {
if (unlikely(PTR_ERR(identity) == -EREMCHG ||
ucred_set_jobid(info, uc);
ucred_set_nid(info, uc);
ucred_set_audit_enabled(info, uc);
- ucred_set_rbac_roles(info, uc);
uc->uc_valid = UCRED_OLD;
test_64a() {
local testfile=$DIR/$tdir/$tfile
+ local srv_uc=""
local rbac
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
stack_trap cleanup_64 EXIT
mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
setup_64
byfid_ops \
chlg_ops \
fscrypt_admin \
+ $srv_uc \
;
do
[[ "$rbac" =~ "$role" ]] ||
error "role '$role' not in default '$rbac'"
done
+ rbac="file_perms"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 \
- --property rbac --value file_perms
+ --property rbac --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
touch $testfile
stack_trap "set +vx"
$LFS project -p 1000 $testfile || error "setting project failed"
set +vx
rm -f $testfile
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
+ rbac="none"
+ if [ -z "$srv_uc" ]; then
+ rbac="none"
+ else
+ rbac="$srv_uc"
+ fi
+ do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
touch $testfile
set -vx
test_64b() {
local testdir=$DIR/$tdir/${tfile}.d
local dir_restripe
+ local srv_uc=""
+ local rbac
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
(( MDSCOUNT >= 2 )) || skip "mdt count $MDSCOUNT, skipping dne_ops role"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
stack_trap cleanup_64 EXIT
mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
setup_64
error "enabling dir_restripe failed"
stack_trap "do_nodes $(comma_list $(all_mdts_nodes)) \
$LCTL set_param mdt.*.enable_dir_restripe=$dir_restripe" EXIT
+ rbac="dne_ops"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
- --value dne_ops
+ --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
$LFS mkdir -i 0 ${testdir}_for_migr ||
error "$LFS mkdir ${testdir}_for_migr failed (1)"
$LFS mkdir -i 1 ${testdir}_mdt1 ||
error "$LFS mkdir ${testdir}_mdt1 failed (2)"
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
+ rbac="none"
+ if [ -z "$srv_uc" ]; then
+ rbac="none"
+ else
+ rbac="$srv_uc"
+ fi
+ do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
set -vx
$LFS mkdir -i 1 $testdir && error "$LFS mkdir should fail (1)"
run_test 64b "Nodemap enforces dne_ops RBAC roles"
test_64c() {
+ local srv_uc=""
+ local rbac
+
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
stack_trap cleanup_64 EXIT
mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
setup_64
+ rbac="quota_ops"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 \
- --property rbac --value quota_ops
+ --property rbac --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
set -vx
$LFS setquota -u $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT ||
$LFS setquota -p 1000 --delete $MOUNT
set +vx
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
+ rbac="none"
+ if [ -z "$srv_uc" ]; then
+ rbac="none"
+ else
+ rbac="$srv_uc"
+ fi
+ do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
set -vx
test_64d() {
local testfile=$DIR/$tdir/$tfile
+ local srv_uc=""
+ local rbac
local fid
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
stack_trap cleanup_64 EXIT
mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
setup_64
+ rbac="byfid_ops"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 \
- --property rbac --value byfid_ops
+ --property rbac --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
touch $testfile
lfs rmfid $MOUNT $fid || error "lfs rmfid failed"
set +vx
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
+ rbac="none"
+ if [ -z "$srv_uc" ]; then
+ rbac="none"
+ else
+ rbac="$srv_uc"
+ fi
+ do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
touch $testfile
test_64e() {
local testfile=$DIR/$tdir/$tfile
local testdir=$DIR/$tdir/${tfile}.d
+ local srv_uc=""
+ local rbac
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
stack_trap cleanup_64 EXIT
mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
setup_64
mkdir $testdir || error "failed to mkdir $testdir"
touch $testfile || error "failed to touch $testfile"
+ rbac="chlg_ops"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 \
- --property rbac --value chlg_ops
+ --property rbac --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
# access changelogs
rm -rf $testdir $testfile || error "rm -rf $testdir $testfile failed"
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none
+ rbac="none"
+ if [ -z "$srv_uc" ]; then
+ rbac="none"
+ else
+ rbac="$srv_uc"
+ fi
+ do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
# do some IOs
changelog_clear 0 && error "clear changelogs should fail"
rm -rf $testdir $testfile
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value all
+ do_facet mgs $LCTL nodemap_modify --name c0 \
+ --property rbac --value all ||
+ error "setting rbac all failed (3)"
wait_nm_sync c0 rbac
}
run_test 64e "Nodemap enforces chlg_ops RBAC roles"
local cli_enc
local policy
local protector
+ local srv_uc=""
+ local rbac
(( MDS1_VERSION >= $(version_code 2.15.54) )) ||
skip "Need MDS >= 2.15.54 for role-based controls"
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) &&
+ srv_uc="server_upcall"
+
cli_enc=$($LCTL get_param mdc.*.import | grep client_encryption)
[ -n "$cli_enc" ] || skip "Need enc support, skip fscrypt_admin role"
which fscrypt || skip "Need fscrypt, skip fscrypt_admin role"
stack_trap "rm -rf $MOUNT/.fscrypt"
# file_perms is required because fscrypt uses chmod/chown
+ rbac="fscrypt_admin,file_perms"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
- --value fscrypt_admin,file_perms
+ --value $rbac ||
+ error "setting rbac $rbac failed (1)"
wait_nm_sync c0 rbac
mkdir -p $vaultdir
cancel_lru_locks
# file_perms is required because fscrypt uses chmod/chown
+ rbac="file_perms"
+ [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc"
do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \
- --value file_perms
+ --value $rbac ||
+ error "setting rbac $rbac failed (2)"
wait_nm_sync c0 rbac
set -vx
set +vx
cancel_lru_locks
- do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value all
+ do_facet mgs $LCTL nodemap_modify --name c0 \
+ --property rbac --value all ||
+ error "setting rbac all failed (3)"
wait_nm_sync c0 rbac
set -vx
}
run_test 64f "Nodemap enforces fscrypt_admin RBAC roles"
+test_64g() {
+ local testfile=$DIR/$tdir/$tfile
+
+ (( MDS1_VERSION >= $(version_code 2.16.50) )) ||
+ skip "Need MDS >= 2.16.50 for role-based controls"
+
+ # Add groups, and client to new group, on client only.
+ # Server is not aware.
+ groupadd -g 5000 grptest64g1
+ stack_trap "groupdel grptest64g1" EXIT
+ groupadd -g 5001 grptest64g2
+ stack_trap "groupdel grptest64g2" EXIT
+ groupadd -g 5002 grptest64g3
+ stack_trap "groupdel grptest64g3" EXIT
+
+ mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+ chmod 750 $DIR/$tdir
+ chgrp grptest64g1 $DIR/$tdir
+ echo hi > $DIR/$tdir/fileA
+ chmod 640 $DIR/$tdir/fileA
+ chgrp grptest64g3 $DIR/$tdir/fileA
+ setfacl -m g:grptest64g2:r $DIR/$tdir/fileA
+ ls -lR $DIR/$tdir
+
+ setup_64
+ stack_trap cleanup_64 EXIT
+
+ # remove server_upcall from rbac roles,
+ # to make this client use INTERNAL upcall
+ do_facet mgs $LCTL nodemap_modify --name c0 \
+ --property rbac --value file_perms ||
+ error "setting rbac file_perms failed"
+ wait_nm_sync c0 rbac
+
+ $RUNAS cat $DIR/$tdir/fileA && error "cat $DIR/$tdir/fileA should fail"
+ $RUNAS -G 5000,5001 cat $DIR/$tdir/fileA ||
+ error "cat $DIR/$tdir/fileA failed"
+}
+run_test 64g "Nodemap enforces server_upcall RBAC role"
+
look_for_files() {
local pattern=$1
local neg=$2