RETURN(0);
}
+static void dump_capa_hmac(char *buf, char *key)
+{
+ int i, n = 0;
+
+ for (i = 0; i < CAPA_DIGEST_SIZE; i++)
+ n += sprintf(buf + n, "%02x", (unsigned char) key[i]);
+}
+
int
filter_verify_capa(int cmd, struct obd_export *exp, struct lustre_capa *capa)
{
struct filter_obd *filter = &obd->u.filter;
struct obd_capa *ocapa;
struct lustre_capa tcapa;
- struct filter_capa_key *rkey = NULL, *bkey = NULL, *tmp;
- __u8 hmac_key[CAPA_KEY_LEN];
+ struct filter_capa_key *rkey = NULL, *bkey = NULL, *tmp, capa_keys[2];
int rc = 0;
/* capability is disabled */
RETURN(-ESTALE);
}
- ocapa = capa_get(capa->lc_uid, capa->lc_op, capa->lc_mdsid,
- capa->lc_ino, capa->lc_igen, FILTER_CAPA);
+ ocapa = filter_capa_get(capa);
verify:
if (ocapa) {
+ struct timeval tv;
+
/* fo_capa_lock protects capa too */
+ do_gettimeofday(&tv);
spin_lock(&filter->fo_capa_lock);
if (capa->lc_keyid == ocapa->c_capa.lc_keyid) {
rc = memcmp(capa, &ocapa->c_capa, sizeof(*capa));
goto new_capa;
}
- if (rc && __capa_is_to_expire(ocapa)) {
+ if (rc && __capa_is_to_expire(ocapa, &tv)) {
/* client should use new expiry now */
ocapa->c_bvalid = 0;
goto new_capa;
}
spin_unlock(&filter->fo_capa_lock);
+ if (rc) {
+ char *key1 = NULL, *key2 = NULL;
+ OBD_ALLOC(key1, CAPA_DIGEST_SIZE * 2 + 1);
+ OBD_ALLOC(key2, CAPA_DIGEST_SIZE * 2 + 1);
+ if (key1 && key2) {
+ dump_capa_hmac(key1, capa->lc_hmac);
+ dump_capa_hmac(key2, ocapa->c_capa.lc_hmac);
+ DEBUG_CAPA(D_ERROR, capa,
+ "access denied for (%s != %s)",
+ key1, key2);
+ DEBUG_CAPA(D_ERROR, &ocapa->c_capa, "used capa");
+ }
+ if (key1)
+ OBD_FREE(key1, CAPA_DIGEST_SIZE * 2 + 1);
+ if (key2)
+ OBD_FREE(key2, CAPA_DIGEST_SIZE * 2 + 1);
+ }
capa_put(ocapa);
RETURN(rc ? -EACCES : 0);
}
}
LASSERT(rkey);
-
- memcpy(&tcapa, capa, sizeof(tcapa));
- tcapa.lc_keyid = rkey->k_key.lk_keyid;
- memcpy(hmac_key, rkey->k_key.lk_key, sizeof(hmac_key));
+ capa_keys[0] = *rkey;
+ if (bkey)
+ capa_keys[1] = *bkey;
spin_unlock(&filter->fo_capa_lock);
- capa_hmac(filter->fo_capa_hmac, hmac_key, &tcapa);
+ tcapa = *capa;
+ tcapa.lc_keyid = capa_keys[0].k_key.lk_keyid;
+ capa_hmac(filter->fo_capa_hmac, capa_keys[0].k_key.lk_key, &tcapa);
/* store in capa cache */
- ocapa = capa_renew(capa, FILTER_CAPA);
+ ocapa = capa_renew(&tcapa, FILTER_CAPA);
if (!ocapa)
GOTO(out, rc = -ENOMEM);
if (bkey) {
- spin_lock(&filter->fo_capa_lock);
- tcapa.lc_keyid = bkey->k_key.lk_keyid;
- memcpy(hmac_key, bkey->k_key.lk_key, sizeof(hmac_key));
- ocapa->c_bkeyid = bkey->k_key.lk_keyid;
- spin_unlock(&filter->fo_capa_lock);
-
- capa_hmac(filter->fo_capa_hmac, bkey->k_key.lk_key, &tcapa);
+ tcapa.lc_keyid = capa_keys[1].k_key.lk_keyid;
+ capa_hmac(filter->fo_capa_hmac, capa_keys[1].k_key.lk_key,
+ &tcapa);
spin_lock(&filter->fo_capa_lock);
memcpy(ocapa->c_bhmac, tcapa.lc_hmac, sizeof(ocapa->c_bhmac));
+ ocapa->c_bkeyid = capa_keys[1].k_key.lk_keyid;
ocapa->c_bvalid = 1;
spin_unlock(&filter->fo_capa_lock);
}