ENTRY;
+ rc = mdt_check_ucred(info);
+ if (rc)
+ RETURN(err_serious(rc));
+
if (MDT_FAIL_CHECK(OBD_FAIL_MDS_GETSTATUS_PACK))
RETURN(err_serious(-ENOMEM));
OBD_FAIL_TIMEOUT(OBD_FAIL_MDS_STATFS_LCW_SLEEP,
(MDT_SERVICE_WATCHDOG_TIMEOUT / 1000) + 1);
+ rc = mdt_check_ucred(info);
+ if (rc)
+ RETURN(err_serious(rc));
if (MDT_FAIL_CHECK(OBD_FAIL_MDS_STATFS_PACK)) {
rc = err_serious(-ENOMEM);
repbody->eadatasize = 0;
repbody->aclsize = 0;
- if (reqbody->valid & OBD_MD_FLRMTPERM) {
+ if (reqbody->valid & OBD_MD_FLRMTPERM)
rc = mdt_init_ucred(info, reqbody);
- if (rc)
- GOTO(out, rc);
- }
+ else
+ rc = mdt_check_ucred(info);
+ if (rc)
+ GOTO(out, rc);
/* don't check capability at all, because rename might
* getattr for remote obj, and at that time no capability
if (reqbody == NULL || repbody == NULL)
RETURN(err_serious(-EFAULT));
+ rc = mdt_check_ucred(info);
+ if (rc)
+ RETURN(err_serious(rc));
+
/*
* prepare @rdpg before calling lower layers and transfer itself. Here
* reqbody->size contains offset of where to start to read and
identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
if (!identity) {
- CERROR("Deny access without identity: uid %d\n",
- ucred->mu_fsuid);
+ CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
RETURN(-EACCES);
}
RETURN(rc);
}
+int mdt_check_ucred(struct mdt_thread_info *info)
+{
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct mdt_export_data *med = mdt_req2med(req);
+ struct mdt_device *mdt = info->mti_mdt;
+ struct ptlrpc_user_desc *pud = req->rq_user_desc;
+ struct md_ucred *ucred = mdt_ucred(info);
+ struct mdt_identity *identity;
+ lnet_nid_t peernid = req->rq_peer.nid;
+
+ ENTRY;
+
+ if ((ucred->mu_valid == UCRED_OLD) || (ucred->mu_valid == UCRED_NEW))
+ RETURN(0);
+
+ /* !rq_user_desc means null security, maybe inter-mds ops */
+ if (!req->rq_user_desc)
+ RETURN(0);
+
+ if (req->rq_auth_gss && req->rq_auth_uid == INVALID_UID) {
+ CWARN("user not authenticated, deny access!\n");
+ RETURN(-EACCES);
+ }
+
+ /* sanity check: if we use strong authentication, we expect the
+ * uid which client claimed is true */
+ if (req->rq_auth_gss) {
+ if (med->med_rmtclient) {
+ if (ptlrpc_user_desc_do_idmap(req, pud))
+ RETURN(-EACCES);
+
+ if (req->rq_auth_mapped_uid != pud->pud_uid) {
+ CERROR("remote client "LPU64": auth uid %u "
+ "while client claim %u:%u/%u:%u\n",
+ peernid, req->rq_auth_uid, pud->pud_uid,
+ pud->pud_gid, pud->pud_fsuid,
+ pud->pud_fsgid);
+ RETURN(-EACCES);
+ }
+ } else {
+ if (req->rq_auth_uid != pud->pud_uid) {
+ CERROR("local client "LPU64": auth uid %u "
+ "while client claim %u:%u/%u:%u\n",
+ peernid, req->rq_auth_uid, pud->pud_uid,
+ pud->pud_gid, pud->pud_fsuid,
+ pud->pud_fsgid);
+ RETURN(-EACCES);
+ }
+ }
+ }
+
+ if (is_identity_get_disabled(mdt->mdt_identity_cache) &&
+ med->med_rmtclient) {
+ CERROR("remote client must run with identity_get enabled!\n");
+ RETURN(-EACCES);
+ }
+
+ identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
+ if (!identity) {
+ CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
+ RETURN(-EACCES);
+ }
+
+ mdt_identity_put(mdt->mdt_identity_cache, identity);
+
+ RETURN(0);
+}
+
int mdt_init_ucred(struct mdt_thread_info *info, struct mdt_body *body)
{
struct ptlrpc_request *req = mdt_info_req(info);