summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2022-08-08 19:46:03 +0100
committerJeremy Harris <jgh146exb@wizmail.org>2022-08-08 21:48:43 +0100
commitef57b25bfa7623c3f8a8e65f927165c4ddc7c43b (patch)
treea4953443e4dd7b8285328ead652fbbf98d0bbb2d /src
parent93c722ce0549360af68269f088f4e59ed8fc130e (diff)
Symlink following for TLS creds files
Diffstat (limited to 'src')
-rw-r--r--src/src/tls.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/src/tls.c b/src/src/tls.c
index 3ed37bbb0..76e72b5f5 100644
--- a/src/src/tls.c
+++ b/src/src/tls.c
@@ -143,15 +143,29 @@ static BOOL
tls_set_one_watch(const uschar * filename)
# ifdef EXIM_HAVE_INOTIFY
{
+uschar buf[PATH_MAX];
+ssize_t len;
uschar * s;
if (Ustrcmp(filename, "system,cache") == 0) return TRUE;
-
if (!(s = Ustrrchr(filename, '/'))) return FALSE;
+
+for (unsigned loop = 20;
+ (len = readlink(CCS filename, CS buf, sizeof(buf))) >= 0; )
+ { /* a symlink */
+ if (--loop == 0) { errno = ELOOP; return FALSE; }
+ filename = buf[0] == '/'
+ ? string_copyn(buf, (unsigned)len) /* mem released by tls_set_watch */
+ : string_sprintf("%.*s/%.*s", (int)(s - filename), (int)len);
+ s = Ustrrchr(filename, '/');
+ }
+if (errno != EINVAL)
+ return FALSE; /* other error */
+
+/* not a symlink */
s = string_copyn(filename, s - filename); /* mem released by tls_set_watch */
-DEBUG(D_tls) debug_printf("watch dir '%s'\n", s);
-/*XXX unclear what effect symlinked files will have for inotify */
+DEBUG(D_tls) debug_printf("watch dir '%s'\n", s);
if (inotify_add_watch(tls_watch_fd, CCS s,
IN_ONESHOT | IN_CLOSE_WRITE | IN_DELETE | IN_DELETE_SELF