cifs.upcall: negatively instantiate keys on error
authorJeff Layton <jlayton@redhat.com>
Sat, 16 Aug 2008 18:30:20 +0000 (14:30 -0400)
committerKarolin Seeger <kseeger@samba.org>
Mon, 18 Aug 2008 13:09:16 +0000 (15:09 +0200)
When a request-key upcall exits without instantiating a key, the kernel
will negatively instantiate the key with a 60s timeout. Older kernels,
however seem to also link that key into the session keyring. This
behavior can interefere with subsequent mount attempts until the
key times out. The next request_key() call will get this negative key
even if the upcall would have worked the second time.

Fix this by having cifs.upcall negatively instantiate the key itself
with a 1s timeout and don't attach it to the session keyring.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
(cherry picked from commit 7e05ff65a7907bf34e2d422f7c941002cfb86971)

source/client/cifs.upcall.c

index 5a2a22a73cac02e66b20ea57d7f1491104c58ebb..aa5eb57310a9e2bb823519451ce23e4df99accbe 100644 (file)
@@ -213,7 +213,7 @@ int main(const int argc, char *const argv[])
        DATA_BLOB secblob = data_blob_null;
        DATA_BLOB sess_key = data_blob_null;
        secType_t sectype;
-       key_serial_t key;
+       key_serial_t key = 0;
        size_t datalen;
        long rc = 1;
        uid_t uid;
@@ -250,6 +250,7 @@ int main(const int argc, char *const argv[])
        errno = 0;
        key = strtol(argv[optind], NULL, 10);
        if (errno != 0) {
+               key = 0;
                syslog(LOG_WARNING, "Invalid key format: %s", strerror(errno));
                goto out;
        }
@@ -361,7 +362,14 @@ int main(const int argc, char *const argv[])
        /* BB: maybe we need use timeout for key: for example no more then
         * ticket lifietime? */
        /* keyctl_set_timeout( key, 60); */
-      out:
+out:
+       /*
+        * on error, negatively instantiate the key ourselves so that we can
+        * make sure the kernel doesn't hang it off of a searchable keyring
+        * and interfere with the next attempt to instantiate the key.
+        */
+       if (rc != 0  && key == 0)
+               keyctl_negate(key, 1, KEY_REQKEY_DEFL_DEFAULT);
        data_blob_free(&secblob);
        data_blob_free(&sess_key);
        SAFE_FREE(hostname);