]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Split off mail_storage_service_update_chroot()
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Fri, 20 Jan 2023 02:32:04 +0000 (04:32 +0200)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Mon, 20 Nov 2023 12:20:55 +0000 (14:20 +0200)
src/lib-storage/mail-storage-service.c

index 99e32123e12a15e7dbd7996696442dcd26d5e923..23af5a31ece82cd9ae4fa653bdbb0dd0e1089ac0 100644 (file)
@@ -1139,6 +1139,45 @@ mail_storage_service_generate_session_id(pool_t pool, const char *prefix)
 
 }
 
+static void
+mail_storage_service_update_chroot(struct mail_storage_service_user *user,
+                                  struct mail_storage_service_privileges *priv)
+{
+       bool temp_priv_drop =
+               (user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
+       /* we can't chroot if we want to switch between users. there's
+          not much point either (from security point of view). but if we're
+          already chrooted, we'll just have to continue and hope that the
+          current chroot is the same as the wanted chroot */
+       bool use_chroot = !temp_priv_drop ||
+               restrict_access_get_current_chroot() != NULL;
+
+       size_t len = strlen(priv->chroot);
+       if (len > 2 && strcmp(priv->chroot + len - 2, "/.") == 0 &&
+           strncmp(priv->home, priv->chroot, len - 2) == 0) {
+               /* mail_chroot = /chroot/. means that the home dir already
+                  contains the chroot dir. remove it from home. */
+               if (use_chroot) {
+                       priv->home += len - 2;
+                       if (*priv->home == '\0')
+                               priv->home = "/";
+                       priv->chroot = t_strndup(priv->chroot, len - 2);
+
+                       set_keyval(user, "mail_home", priv->home);
+                       set_keyval(user, "mail_chroot", priv->chroot);
+               }
+       } else if (len > 0 && !use_chroot) {
+               /* we're not going to chroot. fix home directory so we can
+                  access it. */
+               if (*priv->home == '\0' || strcmp(priv->home, "/") == 0)
+                       priv->home = priv->chroot;
+               else
+                       priv->home = t_strconcat(priv->chroot, priv->home, NULL);
+               priv->chroot = "";
+               set_keyval(user, "mail_home", priv->home);
+       }
+}
+
 static int
 mail_storage_service_lookup_real(struct mail_storage_service_ctx *ctx,
                                 const struct mail_storage_service_input *input,
@@ -1400,12 +1439,10 @@ mail_storage_service_next_real(struct mail_storage_service_ctx *ctx,
 {
        struct mail_storage_service_privileges priv;
        const char *error;
-       size_t len;
        bool allow_root =
                (user->flags & MAIL_STORAGE_SERVICE_FLAG_ALLOW_ROOT) != 0;
        bool temp_priv_drop =
                (user->flags & MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP) != 0;
-       bool use_chroot;
 
        *mail_user_r = NULL;
 
@@ -1419,38 +1456,7 @@ mail_storage_service_next_real(struct mail_storage_service_ctx *ctx,
                return -2;
        }
 
-       /* we can't chroot if we want to switch between users. there's
-          not much point either (from security point of view). but if we're
-          already chrooted, we'll just have to continue and hope that the
-          current chroot is the same as the wanted chroot */
-       use_chroot = !temp_priv_drop ||
-               restrict_access_get_current_chroot() != NULL;
-
-       len = strlen(priv.chroot);
-       if (len > 2 && strcmp(priv.chroot + len - 2, "/.") == 0 &&
-           strncmp(priv.home, priv.chroot, len - 2) == 0) {
-               /* mail_chroot = /chroot/. means that the home dir already
-                  contains the chroot dir. remove it from home. */
-               if (use_chroot) {
-                       priv.home += len - 2;
-                       if (*priv.home == '\0')
-                               priv.home = "/";
-                       priv.chroot = t_strndup(priv.chroot, len - 2);
-
-                       set_keyval(user, "mail_home", priv.home);
-                       set_keyval(user, "mail_chroot", priv.chroot);
-               }
-       } else if (len > 0 && !use_chroot) {
-               /* we're not going to chroot. fix home directory so we can
-                  access it. */
-               if (*priv.home == '\0' || strcmp(priv.home, "/") == 0)
-                       priv.home = priv.chroot;
-               else
-                       priv.home = t_strconcat(priv.chroot, priv.home, NULL);
-               priv.chroot = "";
-               set_keyval(user, "mail_home", priv.home);
-       }
-
+       mail_storage_service_update_chroot(user, &priv);
        mail_storage_service_init_log(ctx, user);
 
        /* create ioloop context regardless of logging. it's also used by