From: Timo Sirainen Date: Fri, 20 Jan 2023 02:32:04 +0000 (+0200) Subject: lib-storage: Split off mail_storage_service_update_chroot() X-Git-Tag: 2.4.0~2282 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4a941b3916ddd63651a04a5d05867737434e7578;p=thirdparty%2Fdovecot%2Fcore.git lib-storage: Split off mail_storage_service_update_chroot() --- diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index 99e32123e1..23af5a31ec 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -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