it is still possible to lock or unlock encrypted directories,
as these operations only need read access to fscrypt metadata.
.br
+- hsm_ops, to control whether clients can carry out HSM actions.
+.br
- ignore_root_prjquota, so that project quota is not enforced for the root user.
.br
- quota_ops, to allow quota modifications.
{ NODEMAP_RBAC_FSCRYPT_ADMIN, "fscrypt_admin" },
{ NODEMAP_RBAC_SERVER_UPCALL, "server_upcall" },
{ NODEMAP_RBAC_IGN_ROOT_PRJQUOTA, "ignore_root_prjquota" },
+ { NODEMAP_RBAC_HSM_OPS, "hsm_ops" },
};
struct nodemap_pde {
int uc_rbac_fscrypt_admin:1;
int uc_rbac_server_upcall:1;
int uc_rbac_ignore_root_prjquota:1;
+ int uc_rbac_hsm_ops:1;
};
struct lu_ucred *lu_ucred(const struct lu_env *env);
NODEMAP_RBAC_FSCRYPT_ADMIN = 0x00000020,
NODEMAP_RBAC_SERVER_UPCALL = 0x00000040,
NODEMAP_RBAC_IGN_ROOT_PRJQUOTA = 0x00000080,
+ NODEMAP_RBAC_HSM_OPS = 0x00000100,
NODEMAP_RBAC_NONE = (__u32)~(NODEMAP_RBAC_FILE_PERMS |
NODEMAP_RBAC_DNE_OPS |
NODEMAP_RBAC_QUOTA_OPS |
NODEMAP_RBAC_CHLG_OPS |
NODEMAP_RBAC_FSCRYPT_ADMIN |
NODEMAP_RBAC_SERVER_UPCALL |
- NODEMAP_RBAC_IGN_ROOT_PRJQUOTA),
+ NODEMAP_RBAC_IGN_ROOT_PRJQUOTA |
+ NODEMAP_RBAC_HSM_OPS),
NODEMAP_RBAC_ALL = 0xFFFFFFFF, /* future caps ON by default */
};
uc->uc_rbac_fscrypt_admin = 1;
uc->uc_rbac_server_upcall = 1;
uc->uc_rbac_ignore_root_prjquota = 1;
+ uc->uc_rbac_hsm_ops = 1;
RETURN(0);
}
mdt_ucred(info)->uc_rbac_fscrypt_admin = 1;
mdt_ucred(info)->uc_rbac_server_upcall = 1;
mdt_ucred(info)->uc_rbac_ignore_root_prjquota = 1;
+ mdt_ucred(info)->uc_rbac_hsm_ops = 1;
rc = mdt_add_dirty_flag(info, mfd->mfd_object, &info->mti_attr);
lu_context_exit(&ses);
return false;
is_admin = cap_raised(mdt_ucred(info)->uc_cap, CAP_SYS_ADMIN);
+ if (!mdt_ucred(info)->uc_rbac_hsm_ops)
+ is_admin = false;
mdt_exit_ucred(info);
rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
if (rc < 0)
GOTO(out, rc = err_serious(rc));
+ if (!mdt_ucred(info)->uc_rbac_hsm_ops)
+ GOTO(out_ucred, rc = -EACCES);
lh = &info->mti_lh[MDT_LH_CHILD];
rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP |
if (rc)
GOTO(out, rc);
+ if (!mdt_ucred(info)->uc_rbac_hsm_ops)
+ GOTO(out_ucred, rc = -EACCES);
+
switch (hr->hr_action) {
/* code to be removed in hsm1_merge and final patch */
case HUA_RELEASE:
uc->uc_rbac_server_upcall = !!(rbac & NODEMAP_RBAC_SERVER_UPCALL);
uc->uc_rbac_ignore_root_prjquota =
!!(rbac & NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
+ uc->uc_rbac_hsm_ops = !!(rbac & NODEMAP_RBAC_HSM_OPS);
}
static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
if (mdt_rdonly(info->mti_exp))
RETURN(-EROFS);
+ if (!uc->uc_rbac_hsm_ops)
+ RETURN(-EACCES);
+
data = req_capsule_client_get(info->mti_pill, &RMF_CLOSE_DATA);
if (data == NULL)
RETURN(-EPROTO);
uc->uc_rbac_fscrypt_admin = 1;
uc->uc_rbac_server_upcall = 1;
uc->uc_rbac_ignore_root_prjquota = 1;
+ uc->uc_rbac_hsm_ops = 1;
task = kthread_create(mdt_restriper_main, info, "mdt_restriper_%03d",
mdt_seq_site(mdt)->ss_node_id);
ucred->uc_rbac_fscrypt_admin = 1;
ucred->uc_rbac_server_upcall = 1;
ucred->uc_rbac_ignore_root_prjquota = 1;
+ ucred->uc_rbac_hsm_ops = 1;
}
static void echo_ucred_fini(struct lu_env *env)
(unsigned)NODEMAP_RBAC_SERVER_UPCALL);
LASSERTF(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA == 0x00000080UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
- LASSERTF(NODEMAP_RBAC_NONE == 0xffffff00UL, "found 0x%.8xUL\n",
+ LASSERTF(NODEMAP_RBAC_HSM_OPS == 0x00000100UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_HSM_OPS);
+ LASSERTF(NODEMAP_RBAC_NONE == 0xfffffe00UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_NONE);
LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_ALL);
}
run_test 410 "lfs data_version -s allows release of force-archived file"
+cleanup_411() {
+ local nm=$1
+
+ do_facet mgs $LCTL nodemap_del $nm
+ do_facet mgs $LCTL nodemap_activate 0
+ wait_nm_sync active
+}
+
+test_411()
+{
+ local client_ip=$(host_nids_address $HOSTNAME $NETTYPE)
+ local client_nid=$(h2nettype $client_ip)
+ local tf1=$DIR/$tdir/fileA
+ local tf2=$DIR/$tdir/fileB
+ local nm=test_411
+ local roles
+ local fid
+
+ do_facet mgs $LCTL nodemap_modify --name default \
+ --property admin --value 1
+ do_facet mgs $LCTL nodemap_modify --name default \
+ --property trusted --value 1
+ do_facet mgs $LCTL nodemap_add $nm
+ do_facet mgs $LCTL nodemap_add_range \
+ --name $nm --range $client_nid
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property admin --value 1
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property trusted --value 1
+ do_facet mgs $LCTL nodemap_activate 1
+ stack_trap "cleanup_411 $nm" EXIT
+ wait_nm_sync active
+ wait_nm_sync $nm trusted_nodemap
+
+ roles=$(do_facet mds $LCTL get_param -n nodemap.$nm.rbac)
+ [[ "$roles" =~ "hsm_ops" ]] ||
+ skip "role 'hsm_ops' not supported by server"
+
+ mkdir_on_mdt0 $DIR/$tdir || error "mkdir $DIR/$tdir failed"
+ echo hi > $tf1 || error "create $tf1 failed"
+ echo hi > $tf2 || error "create $tf2 failed"
+
+ copytool setup
+
+ # with hsm_ops role, all ops should pass
+ fid=$(path2fid $tf1)
+ $LFS hsm_state $tf1 || error "hsm_state $tf1 failed"
+ $LFS hsm_archive $tf1 || error "hsm_archive $tf1 failed"
+ wait_request_state $fid ARCHIVE SUCCEED
+ $LFS hsm_release $tf1 || error "hsm_release $tf1 failed"
+ check_hsm_flags $tf1 "0x0000000d"
+ $LFS hsm_restore $tf1 || error "hsm_restore $tf1 failed"
+ wait_request_state $fid RESTORE SUCCEED
+ $LFS hsm_remove $tf1 || error "hsm_remove $tf1 failed"
+ wait_request_state $fid REMOVE SUCCEED
+ check_hsm_flags $tf1 "0x00000000"
+ $LFS hsm_set --exists $tf1 || error "hsm_set $tf1 failed"
+ check_hsm_flags $tf1 "0x00000001"
+ $LFS hsm_clear --exists $tf1 || error "hsm_clear $tf1 failed"
+ check_hsm_flags $tf1 "0x00000000"
+
+ # remove hsm_ops from rbac roles
+ roles=$(echo "$roles" | sed 's/hsm_ops,//;s/,hsm_ops//;s/^hsm_ops,//')
+ do_facet mgs $LCTL nodemap_modify --name $nm \
+ --property rbac --value $roles
+ wait_nm_sync $nm rbac
+
+ # without hsm_ops role, all ops should fail
+ fid=$(path2fid $tf2)
+ $LFS hsm_state $tf2 || error "hsm_state $tf2 failed"
+ $LFS hsm_archive $tf2 && error "hsm_archive $tf2 succeeded"
+ $LFS hsm_release $tf2 && error "hsm_release $tf2 succeeded"
+ check_hsm_flags $tf2 "0x00000000"
+ $LFS hsm_restore $tf2 && error "hsm_restore $tf2 succeeded"
+ $LFS hsm_remove $tf2 && error "hsm_remove $tf2 succeeded"
+ check_hsm_flags $tf2 "0x00000000"
+ $LFS hsm_set --exists $tf2 && error "hsm_set $tf2 succeeded"
+ check_hsm_flags $tf2 "0x00000000"
+ $LFS hsm_clear --exists $tf2 && error "hsm_clear $tf2 succeeded"
+ check_hsm_flags $tf2 "0x00000000"
+}
+run_test 411 "hsm_ops rbac role"
+
test_500()
{
[ "$MDS1_VERSION" -lt $(version_code 2.6.92) ] &&
CHECK_VALUE_X(NODEMAP_RBAC_FSCRYPT_ADMIN);
CHECK_VALUE_X(NODEMAP_RBAC_SERVER_UPCALL);
CHECK_VALUE_X(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
+ CHECK_VALUE_X(NODEMAP_RBAC_HSM_OPS);
CHECK_VALUE_X(NODEMAP_RBAC_NONE);
CHECK_VALUE_X(NODEMAP_RBAC_ALL);
}
(unsigned)NODEMAP_RBAC_SERVER_UPCALL);
LASSERTF(NODEMAP_RBAC_IGN_ROOT_PRJQUOTA == 0x00000080UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_IGN_ROOT_PRJQUOTA);
- LASSERTF(NODEMAP_RBAC_NONE == 0xffffff00UL, "found 0x%.8xUL\n",
+ LASSERTF(NODEMAP_RBAC_HSM_OPS == 0x00000100UL, "found 0x%.8xUL\n",
+ (unsigned)NODEMAP_RBAC_HSM_OPS);
+ LASSERTF(NODEMAP_RBAC_NONE == 0xfffffe00UL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_NONE);
LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n",
(unsigned)NODEMAP_RBAC_ALL);