libceph: set global_id as soon as we get an auth ticket
authorIlya Dryomov <idryomov@gmail.com>
Mon, 21 Jun 2021 10:17:40 +0000 (12:17 +0200)
committerIlya Dryomov <idryomov@gmail.com>
Thu, 24 Jun 2021 19:03:17 +0000 (21:03 +0200)
Commit 61ca49a9105f ("libceph: don't set global_id until we get an
auth ticket") delayed the setting of global_id too much.  It is set
only after all tickets are received, but in pre-nautilus clusters an
auth ticket and the service tickets are obtained in separate steps
(for a total of three MAuth replies).  When the service tickets are
requested, global_id is used to build an authorizer; if global_id is
still 0 we never get them and fail to establish the session.

Moving the setting of global_id into protocol implementations.  This
way global_id can be set exactly when an auth ticket is received, not
sooner nor later.

Fixes: 61ca49a9105f ("libceph: don't set global_id until we get an auth ticket")
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
include/linux/ceph/auth.h
net/ceph/auth.c
net/ceph/auth_none.c
net/ceph/auth_x.c

index 39425e2f7cb218bbd2e25b65aca5ba4a93e95abd..6b138fa97db85826c8e2f645a7f5706c0d5d4493 100644 (file)
@@ -50,7 +50,7 @@ struct ceph_auth_client_ops {
         * another request.
         */
        int (*build_request)(struct ceph_auth_client *ac, void *buf, void *end);
-       int (*handle_reply)(struct ceph_auth_client *ac,
+       int (*handle_reply)(struct ceph_auth_client *ac, u64 global_id,
                            void *buf, void *end, u8 *session_key,
                            int *session_key_len, u8 *con_secret,
                            int *con_secret_len);
@@ -104,6 +104,8 @@ struct ceph_auth_client {
        struct mutex mutex;
 };
 
+void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id);
+
 struct ceph_auth_client *ceph_auth_init(const char *name,
                                        const struct ceph_crypto_key *key,
                                        const int *con_modes);
index 3a9d44eee941a4396c8063db36df467c509021a3..d2b268a1838e8e24864f049f20befd129d11965f 100644 (file)
@@ -36,7 +36,7 @@ static int init_protocol(struct ceph_auth_client *ac, int proto)
        }
 }
 
-static void set_global_id(struct ceph_auth_client *ac, u64 global_id)
+void ceph_auth_set_global_id(struct ceph_auth_client *ac, u64 global_id)
 {
        dout("%s global_id %llu\n", __func__, global_id);
 
@@ -267,7 +267,7 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac,
                goto out;
        }
 
-       ret = ac->ops->handle_reply(ac, payload, payload_end,
+       ret = ac->ops->handle_reply(ac, global_id, payload, payload_end,
                                    NULL, NULL, NULL, NULL);
        if (ret == -EAGAIN) {
                ret = build_request(ac, true, reply_buf, reply_len);
@@ -276,8 +276,6 @@ int ceph_handle_auth_reply(struct ceph_auth_client *ac,
                goto out;
        }
 
-       set_global_id(ac, global_id);
-
 out:
        mutex_unlock(&ac->mutex);
        return ret;
@@ -485,7 +483,7 @@ int ceph_auth_handle_reply_more(struct ceph_auth_client *ac, void *reply,
        int ret;
 
        mutex_lock(&ac->mutex);
-       ret = ac->ops->handle_reply(ac, reply, reply + reply_len,
+       ret = ac->ops->handle_reply(ac, 0, reply, reply + reply_len,
                                    NULL, NULL, NULL, NULL);
        if (ret == -EAGAIN)
                ret = build_request(ac, false, buf, buf_len);
@@ -503,11 +501,10 @@ int ceph_auth_handle_reply_done(struct ceph_auth_client *ac,
        int ret;
 
        mutex_lock(&ac->mutex);
-       ret = ac->ops->handle_reply(ac, reply, reply + reply_len,
+       ret = ac->ops->handle_reply(ac, global_id, reply, reply + reply_len,
                                    session_key, session_key_len,
                                    con_secret, con_secret_len);
-       if (!ret)
-               set_global_id(ac, global_id);
+       WARN_ON(ret == -EAGAIN || ret > 0);
        mutex_unlock(&ac->mutex);
        return ret;
 }
index aab490a111eb3e5161a334e8ec9836ff2dd4a04e..097e9f8d87a72f254deb58c175d65f6f4ad7af66 100644 (file)
@@ -69,7 +69,7 @@ static int build_request(struct ceph_auth_client *ac, void *buf, void *end)
  * the generic auth code decode the global_id, and we carry no actual
  * authenticate state, so nothing happens here.
  */
-static int handle_reply(struct ceph_auth_client *ac,
+static int handle_reply(struct ceph_auth_client *ac, u64 global_id,
                        void *buf, void *end, u8 *session_key,
                        int *session_key_len, u8 *con_secret,
                        int *con_secret_len)
@@ -77,6 +77,7 @@ static int handle_reply(struct ceph_auth_client *ac,
        struct ceph_auth_none_info *xi = ac->private;
 
        xi->starting = false;
+       ceph_auth_set_global_id(ac, global_id);
        return 0;
 }
 
index cab99c5581b0a39a31f6a811ceeefc593bcdf525..b71b1635916e1712bf0e1723dab1307d06a16bc1 100644 (file)
@@ -597,7 +597,7 @@ bad:
        return -EINVAL;
 }
 
-static int handle_auth_session_key(struct ceph_auth_client *ac,
+static int handle_auth_session_key(struct ceph_auth_client *ac, u64 global_id,
                                   void **p, void *end,
                                   u8 *session_key, int *session_key_len,
                                   u8 *con_secret, int *con_secret_len)
@@ -613,6 +613,7 @@ static int handle_auth_session_key(struct ceph_auth_client *ac,
        if (ret)
                return ret;
 
+       ceph_auth_set_global_id(ac, global_id);
        if (*p == end) {
                /* pre-nautilus (or didn't request service tickets!) */
                WARN_ON(session_key || con_secret);
@@ -661,7 +662,7 @@ e_inval:
        return -EINVAL;
 }
 
-static int ceph_x_handle_reply(struct ceph_auth_client *ac,
+static int ceph_x_handle_reply(struct ceph_auth_client *ac, u64 global_id,
                               void *buf, void *end,
                               u8 *session_key, int *session_key_len,
                               u8 *con_secret, int *con_secret_len)
@@ -695,9 +696,9 @@ static int ceph_x_handle_reply(struct ceph_auth_client *ac,
        switch (op) {
        case CEPHX_GET_AUTH_SESSION_KEY:
                /* AUTH ticket + [connection secret] + service tickets */
-               ret = handle_auth_session_key(ac, &p, end, session_key,
-                                             session_key_len, con_secret,
-                                             con_secret_len);
+               ret = handle_auth_session_key(ac, global_id, &p, end,
+                                             session_key, session_key_len,
+                                             con_secret, con_secret_len);
                break;
 
        case CEPHX_GET_PRINCIPAL_SESSION_KEY: