]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage, imap: Fix token authentication when re-hibernating IMAP session
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 17 Mar 2026 12:30:47 +0000 (14:30 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Thu, 19 Mar 2026 12:16:46 +0000 (12:16 +0000)
Preserve the original session's PID as auth_token_session_pid in userdb
fields next to auth_token field.

src/imap/imap-client-hibernate.c
src/lib-storage/mail-storage-service.c
src/lib-storage/mail-storage-service.h
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h

index ad28469668dce86700cc29fdaa35d0bf72c2bcf1..4a79219c485d508ed12a0ac095aa20f74810bbd0 100644 (file)
@@ -88,12 +88,24 @@ static void imap_hibernate_write_cmd(struct client *client, string_t *cmd,
        if (client->userdb_fields != NULL) {
                string_t *userdb_fields = t_str_new(256);
                unsigned int i;
+               bool have_auth_token_session_pid = FALSE;
 
                for (i = 0; client->userdb_fields[i] != NULL; i++) {
                        if (i > 0)
                                str_append_c(userdb_fields, '\t');
+                       if (str_begins_with(client->userdb_fields[i],
+                                           "auth_token_session_pid="))
+                               have_auth_token_session_pid = TRUE;
                        str_append_tabescaped(userdb_fields, client->userdb_fields[i]);
                }
+               if (!have_auth_token_session_pid) {
+                       if (i > 0)
+                               str_append_c(userdb_fields, '\t');
+                       /* This is picked up by mail-storage-service when
+                          unhibernating. */
+                       str_printfa(userdb_fields, "auth_token_session_pid=%s",
+                                   dec2str(client->user->auth_token_session_pid));
+               }
                str_append(cmd, "\tuserdb_fields=");
                str_append_tabescaped(cmd, str_c(userdb_fields));
        }
@@ -111,7 +123,8 @@ static void imap_hibernate_write_cmd(struct client *client, string_t *cmd,
        }
        str_append(cmd, "\tauth_token=");
        str_append_tabescaped(cmd, user->auth_token);
-       str_printfa(cmd, "\tsession_pid=%s", my_pid);
+       str_printfa(cmd, "\tsession_pid=%s",
+                   dec2str(user->auth_token_session_pid));
        str_append(cmd, "\tstats=");
        str_append_tabescaped(cmd, client_stats(client));
        if (client->command_queue != NULL &&
@@ -316,7 +329,8 @@ bool imap_client_hibernate(struct client **_client, const char **reason_r)
                        "(session_pid=%s auth_token=%s)",
                        client->mailbox == NULL ? "<none>" :
                        mailbox_get_vname(client->mailbox),
-                       my_pid, client->user->auth_token);
+                       dec2str(client->user->auth_token_session_pid),
+                       client->user->auth_token);
                client->disconnected = TRUE;
                client->hibernated = TRUE;
                client_destroy(client, NULL);
index 393aeb51afa607802764b2a7ff4454c3779cfb63..141c7514383ef2b86c739e6e9838c32f61f0d040 100644 (file)
@@ -201,6 +201,13 @@ user_reply_handle(struct mail_storage_service_user *user,
 #endif
                } else if (strcmp(key, "auth_mech") == 0) {
                        user->auth_mech = p_strdup(user->pool, value);
+               } else if (strcmp(key, "auth_token_session_pid") == 0) {
+                       if (str_to_pid(value, &user->auth_token_session_pid) < 0 ||
+                           user->auth_token_session_pid == 0) {
+                               e_error(user->event,
+                                       "userdb returned invalid auth_token_session_pid value %s",
+                                       value);
+                       }
                } else if (strcmp(key, "auth_token") == 0) {
                        user->auth_token = p_strdup(user->pool, value);
                } else if (strcmp(key, "auth_user") == 0) {
@@ -213,6 +220,8 @@ user_reply_handle(struct mail_storage_service_user *user,
                        set_keyvalue(user, key, value);
                }
        }
+       if (user->auth_token != NULL && user->auth_token_session_pid == 0)
+               user->auth_token_session_pid = getpid();
        return 0;
 }
 
@@ -636,6 +645,7 @@ mail_storage_service_init_post(struct mail_storage_service_ctx *ctx,
                mail_user->service;
        mail_user->auth_mech = p_strdup(mail_user->pool, user->auth_mech);
        mail_user->auth_token = p_strdup(mail_user->pool, user->auth_token);
+       mail_user->auth_token_session_pid = user->auth_token_session_pid;
        mail_user->auth_user = p_strdup(mail_user->pool, user->auth_user);
        if (user->input.session_create_time != 0) {
                mail_user->session_create_time =
index 4bb5eab1ace1c9afb8706d6cffc6bdccf64a4740..7d55e0ced811d9a65d39f569d2a1b9e3ed876dde 100644 (file)
@@ -99,6 +99,7 @@ struct mail_storage_service_user {
        struct event *event;
        struct ioloop_context *ioloop_ctx;
        const char *log_prefix, *auth_mech, *auth_token, *auth_user;
+       pid_t auth_token_session_pid;
        const char *master_user;
        const char *local_name;
 
index 9b011ca146d55242cab7ada3de2271aac3495e7c..76018f75cbe3839ab213cc73c292b8e654f82c8e 100644 (file)
@@ -636,6 +636,7 @@ struct mail_user *mail_user_dup(struct mail_user *user)
        user2->protocol = p_strdup(user2->pool, user->protocol);
        user2->auth_mech = p_strdup(user2->pool, user->auth_mech);
        user2->auth_token = p_strdup(user2->pool, user->auth_token);
+       user2->auth_token_session_pid = user->auth_token_session_pid;
        user2->auth_user = p_strdup(user2->pool, user->auth_user);
        user2->session_id = p_strdup(user2->pool, user->session_id);
        user2->session_create_time = user->session_create_time;
index 2baeff362ff5a0b1d558b56f24045aa6f6aaecba..0ea9036d0c0455051a2873916ee50ea27d68e128 100644 (file)
@@ -51,6 +51,7 @@ struct mail_user {
        const char *session_id;
        struct mail_user_connection_data conn;
        const char *auth_mech, *auth_token, *auth_user;
+       pid_t auth_token_session_pid;
        const char *master_user;
        const char *const *userdb_fields;
        const char *const *_alt_usernames;