Exemple #1
0
static int osd_object_auth(const struct lu_env *env, struct dt_object *dt,
			   struct lustre_capa *capa, __u64 opc)
{
	const struct lu_fid	*fid = lu_object_fid(&dt->do_lu);
	struct osd_device	*dev = osd_dev(dt->do_lu.lo_dev);
	int			 rc;

	if (!dev->od_fl_capa)
		return 0;

	if (capa == BYPASS_CAPA)
		return 0;

	if (!capa) {
		CERROR("no capability is provided for fid "DFID"\n", PFID(fid));
		return -EACCES;
	}

	if (!lu_fid_eq(fid, &capa->lc_fid)) {
		DEBUG_CAPA(D_ERROR, capa, "fid "DFID" mismatch with",PFID(fid));
		return -EACCES;
	}

	if (!capa_opc_supported(capa, opc)) {
		DEBUG_CAPA(D_ERROR, capa, "opc "LPX64" not supported by", opc);
		return -EACCES;
	}

	if ((rc = capa_is_sane(env, dev, capa, dev->od_capa_keys))) {
		DEBUG_CAPA(D_ERROR, capa, "insane (rc %d)", rc);
		return -EACCES;
	}

	return 0;
}
Exemple #2
0
static int capa_is_sane(const struct lu_env *env, struct osd_device *dev,
			struct lustre_capa *capa, struct lustre_capa_key *keys)
{
	struct osd_thread_info	*oti = osd_oti_get(env);
	struct obd_capa		*oc;
	int			 i, rc = 0;
	ENTRY;

	oc = capa_lookup(dev->od_capa_hash, capa, 0);
	if (oc) {
		if (capa_is_expired(oc)) {
			DEBUG_CAPA(D_ERROR, capa, "expired");
			rc = -ESTALE;
		}
		capa_put(oc);
		RETURN(rc);
	}

	spin_lock(&capa_lock);
	for (i = 0; i < 2; i++) {
		if (keys[i].lk_keyid == capa->lc_keyid) {
			oti->oti_capa_key = keys[i];
			break;
		}
	}
	spin_unlock(&capa_lock);

	if (i == 2) {
		DEBUG_CAPA(D_ERROR, capa, "no matched capa key");
		RETURN(-ESTALE);
	}

	rc = capa_hmac(oti->oti_capa.lc_hmac, capa, oti->oti_capa_key.lk_key);
	if (rc)
		RETURN(rc);
	if (memcmp(oti->oti_capa.lc_hmac, capa->lc_hmac, sizeof(capa->lc_hmac)))
	{
		DEBUG_CAPA(D_ERROR, capa, "HMAC mismatch");
		RETURN(-EACCES);
	}

	oc = capa_add(dev->od_capa_hash, capa);
	capa_put(oc);

	RETURN(0);
}
Exemple #3
0
static inline void update_capa_timer(struct obd_capa *ocapa, cfs_time_t expiry)
{
	if (cfs_time_before(expiry, ll_capa_timer.expires) ||
	    !timer_pending(&ll_capa_timer)) {
		mod_timer(&ll_capa_timer, expiry);
		DEBUG_CAPA(D_SEC, &ocapa->c_capa,
			   "ll_capa_timer update: %lu/%lu by", expiry, jiffies);
	}
}
Exemple #4
0
static struct obd_capa *osd_capa_get(const struct lu_env *env,
				     struct dt_object *dt,
				     struct lustre_capa *old,
				     __u64 opc)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	const struct lu_fid	*fid = lu_object_fid(&dt->do_lu);
	struct osd_object	*obj = osd_dt_obj(dt);
	struct osd_device	*dev = osd_obj2dev(obj);
	struct lustre_capa_key	*key = &info->oti_capa_key;
	struct lustre_capa	*capa = &info->oti_capa;
	struct obd_capa		*oc;
	int			 rc;
	ENTRY;

	if (!dev->od_fl_capa)
		RETURN(ERR_PTR(-ENOENT));

	LASSERT(dt_object_exists(dt));
	LASSERT(osd_invariant(obj));

	/* renewal sanity check */
	if (old && osd_object_auth(env, dt, old, opc))
		RETURN(ERR_PTR(-EACCES));

	capa->lc_fid = *fid;
	capa->lc_opc = opc;
	capa->lc_uid = 0;
	capa->lc_flags = dev->od_capa_alg << 24;
	capa->lc_timeout = dev->od_capa_timeout;
	capa->lc_expiry = 0;

	oc = capa_lookup(dev->od_capa_hash, capa, 1);
	if (oc) {
		LASSERT(!capa_is_expired(oc));
		RETURN(oc);
	}

	spin_lock(&capa_lock);
	*key = dev->od_capa_keys[1];
	spin_unlock(&capa_lock);

	capa->lc_keyid = key->lk_keyid;
	capa->lc_expiry = cfs_time_current_sec() + dev->od_capa_timeout;

	rc = capa_hmac(capa->lc_hmac, capa, key->lk_key);
	if (rc) {
		DEBUG_CAPA(D_ERROR, capa, "HMAC failed: %d for", rc);
		LBUG();
		RETURN(ERR_PTR(rc));
	}

	oc = capa_add(dev->od_capa_hash, capa);
	RETURN(oc);
}
Exemple #5
0
void mdc_pack_capa(struct ptlrpc_request *req, const struct req_msg_field *field,
		   struct obd_capa *oc)
{
	struct req_capsule *pill = &req->rq_pill;
	struct lustre_capa *c;

	if (oc == NULL) {
		LASSERT(req_capsule_get_size(pill, field, RCL_CLIENT) == 0);
		return;
	}

	c = req_capsule_client_get(pill, field);
	LASSERT(c != NULL);
	capa_cpy(c, oc);
	DEBUG_CAPA(D_SEC, c, "pack");
}
Exemple #6
0
void mdt_dump_capainfo(struct mdt_thread_info *info)
{
	struct lu_capainfo *lci = lu_capainfo_get(info->mti_env);
	int i;

	if (lci == NULL)
		return;

	for (i = 0; i < LU_CAPAINFO_MAX; i++) {
		if (lci->lci_capa[i] == NULL) {
			CERROR("no capa for index %d "DFID"\n",
			       i, PFID(&lci->lci_fid[i]));
			continue;
		}
		if (lci->lci_capa[i] == BYPASS_CAPA) {
			CERROR("bypass for index %d "DFID"\n",
			       i, PFID(&lci->lci_fid[i]));
			continue;
		}
		DEBUG_CAPA(D_ERROR, lci->lci_capa[i], "index %d", i);
	}
}