Whamcloud - gitweb
on OSS compare the whole capa structure because we might have 2 capa only
[fs/lustre-release.git] / lustre / obdfilter / filter_capa.c
index 33c4026..9607b0e 100644 (file)
@@ -208,6 +208,14 @@ int filter_verify_fid(struct obd_export *exp, struct inode *inode,
         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)
 {
@@ -215,8 +223,7 @@ 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 */
@@ -251,11 +258,13 @@ filter_verify_capa(int cmd, struct obd_export *exp, struct lustre_capa *capa)
                 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));
@@ -269,13 +278,30 @@ verify:
                         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);
         }
@@ -304,30 +330,28 @@ new_capa:
         }
 
         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);
         }