]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-storage: Support expanding ~/ to home directory in *_path settings
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 16 Nov 2023 23:20:32 +0000 (01:20 +0200)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 12 Feb 2025 10:34:10 +0000 (12:34 +0200)
These settings will be added by the following commits.

src/lib-storage/mail-storage-settings.c
src/lib-storage/mail-user.c
src/lib-storage/mail-user.h

index 2bb02b590606256096a85668dca2e63757356510..779110ec4346c4247e982b22ceb7b905033de295 100644 (file)
@@ -336,6 +336,18 @@ mail_user_set_get_storage_set(struct mail_user *user)
        return user->_mail_set;
 }
 
+static struct mail_user *mail_storage_event_get_user(struct event *event)
+{
+       struct mail_user *user;
+
+       for (; event != NULL; event = event_get_parent(event)) {
+               user = event_get_ptr(event, SETTINGS_EVENT_MAIL_USER);
+               if (user != NULL)
+                       return user;
+       }
+       i_panic("mail_user not found from event");
+}
+
 static void
 fix_base_path(struct mail_user_settings *set, pool_t pool, const char **str)
 {
@@ -464,10 +476,52 @@ static bool
 mail_storage_settings_apply(struct event *event ATTR_UNUSED, void *_set,
                            const char *key, const char **value,
                            enum setting_apply_flags flags,
-                           const char **error_r ATTR_UNUSED)
+                           const char **error_r)
 {
        struct mail_storage_settings *set = _set;
 
+       unsigned int key_len = strlen(key);
+       if (key_len > 5 && strcmp(key + key_len - 5, "_path") == 0) {
+               unsigned int value_len = strlen(*value);
+               bool truncate = FALSE;
+
+               /* drop trailing '/' and convert ~/ to %{home}/ */
+               if (value_len > 0 && (*value)[value_len-1] == '/')
+                       truncate = TRUE;
+               if ((str_begins_with(*value, "~/") ||
+                    strcmp(*value, "~") == 0) &&
+                   (flags & SETTING_APPLY_FLAG_NO_EXPAND) == 0) {
+#ifndef CONFIG_BINARY
+                       struct mail_user *user =
+                               mail_storage_event_get_user(event);
+                       const char *home;
+                       if (mail_user_get_home(user, &home) > 0)
+                               ;
+                       else if (user->nonexistent) {
+                               /* Nonexistent shared user. Don't fail the user
+                                  creation due to this. */
+                               home = "";
+                       } else {
+                               *error_r = t_strdup_printf(
+                                       "%s setting used home directory (~/) but there is no "
+                                       "mail_home and userdb didn't return it", key);
+                               return FALSE;
+                       }
+                       if (!truncate)
+                               *value = p_strconcat(set->pool, home, *value + 1, NULL);
+                       else T_BEGIN {
+                               *value = p_strconcat(set->pool, home,
+                                       t_strndup(*value + 1, value_len - 2), NULL);
+                       } T_END;
+#else
+                       *error_r = "~/ expansion not supported in config binary";
+                       return FALSE;
+#endif
+               } else if (truncate) {
+                       *value = p_strndup(set->pool, *value, value_len - 1);
+               }
+       }
+
        if (strcmp(key, "mail_location") == 0) {
                set->unexpanded_mail_location = *value;
                set->unexpanded_mail_location_override =
index 8f59a714a440bece051ae71486db55affb8c2436..b5155a7983808c203b28bdc511c8f3dc2f2dbcea 100644 (file)
@@ -95,6 +95,7 @@ mail_user_alloc(struct mail_storage_service_user *service_user)
        user->session_create_time = ioloop_time;
        user->event = event_create(parent_event);
        event_add_category(user->event, &event_category_storage);
+       event_set_ptr(user->event, SETTINGS_EVENT_MAIL_USER, user);
        event_add_str(user->event, "user", username);
 
        /* Register %variable expansion callback function for settings
index 4aa702ca9a975a723f4331c63421c05e01c12490..48cc693ae9c79dd55c78d0320f55f359655e9c44 100644 (file)
@@ -6,6 +6,8 @@
 #include "mail-storage-settings.h"
 #include "process-stat.h"
 
+#define SETTINGS_EVENT_MAIL_USER "mail_user"
+
 struct module;
 struct fs_parameters;
 struct ssl_iostream_settings;