* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
/* Functions concerned with running Exim as a daemon */
}
-/* SIGTERM handler. Try to get the damon pid file removed
+/* SIGTERM handler. Try to get the daemon pid file removed
before exiting. */
static void
the incoming host address and an expanded active_hostname. */
log_close_all();
-interface_address =
-sender_host_address = NULL;
+interface_address = sender_host_name = sender_host_address = NULL;
store_reset(reset_point);
-sender_host_address = NULL;
}
* Listener socket for local work prompts *
*************************************************/
+ssize_t
+daemon_client_sockname(struct sockaddr_un * sup, uschar ** sname)
+{
+#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
+sup->sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
+return offsetof(struct sockaddr_un, sun_path) + 1
+ + snprintf(sup->sun_path+1, sizeof(sup->sun_path)-1, "exim_%d", getpid());
+#else
+*sname = string_sprintf("%s/p_%d", spool_directory, getpid());
+return offsetof(struct sockaddr_un, sun_path)
+ + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s", sname);
+#endif
+}
+
+ssize_t
+daemon_notifier_sockname(struct sockaddr_un * sup)
+{
+#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
+sup->sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
+return offsetof(struct sockaddr_un, sun_path) + 1
+ + snprintf(sup->sun_path+1, sizeof(sup->sun_path)-1, "%s",
+ expand_string(notifier_socket));
+#else
+return offsetof(struct sockaddr_un, sun_path)
+ + snprintf(sup->sun_path, sizeof(sup->sun_path), "%s",
+ expand_string(notifier_socket));
+#endif
+}
+
+
static void
daemon_notifier_socket(void)
{
int fd;
const uschar * where;
struct sockaddr_un sa_un = {.sun_family = AF_UNIX};
-int len;
+ssize_t len;
if (!notifier_socket || !*notifier_socket)
{
(void)fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
#endif
+len = daemon_notifier_sockname(&sa_un);
+
#ifdef EXIM_HAVE_ABSTRACT_UNIX_SOCKETS
-sa_un.sun_path[0] = 0; /* Abstract local socket addr - Linux-specific? */
-len = offsetof(struct sockaddr_un, sun_path) + 1
- + snprintf(sa_un.sun_path+1, sizeof(sa_un.sun_path)-1, "%s",
- expand_string(notifier_socket));
DEBUG(D_any) debug_printf(" @%s\n", sa_un.sun_path+1);
#else /* filesystem-visible and persistent; will neeed removal */
-len = offsetof(struct sockaddr_un, sun_path)
- + snprintf(sa_un.sun_path, sizeof(sa_un.sun_path), "%s",
- expand_string(notifier_socket));
DEBUG(D_any) debug_printf(" %s\n", sa_un.sun_path);
#endif
-if (bind(fd, (const struct sockaddr *)&sa_un, len) < 0)
+if (bind(fd, (const struct sockaddr *)&sa_un, (socklen_t)len) < 0)
{ where = US"bind"; goto bad; }
#ifdef SO_PASSCRED /* Linux */
static uschar queuerun_msgid[MESSAGE_ID_LENGTH+1];
-/* Return TRUE if a sigalrm should be emulated */
+/* The notifier socket has something to read. Pull the message from it, decode
+and do the action.
+
+Return TRUE if a sigalrm should be emulated */
+
static BOOL
daemon_notification(void)
{
{
DEBUG(D_queue_run) debug_printf("%s: sender creds pid %d uid %d gid %d\n",
__FUNCTION__, (int)cr->pid, (int)cr->uid, (int)cr->gid);
- return FALSE;
}
# elif defined(LOCAL_CREDS) /* BSD-ish */
struct sockcred * cr = (struct sockcred *) CMSG_DATA(cp);
{
DEBUG(D_queue_run) debug_printf("%s: sender creds pid ??? uid %d gid %d\n",
__FUNCTION__, (int)cr->sc_uid, (int)cr->sc_gid);
- return FALSE;
}
# endif
break;
(const struct sockaddr *)&sa_un, msg.msg_namelen) < 0)
log_write(0, LOG_MAIN|LOG_PANIC,
"%s: sendto: %s\n", __FUNCTION__, strerror(errno));
- return FALSE;
+ break;
}
+
+ case NOTIFY_REGEX:
+ regex_at_daemon(buf);
+ break;
}
return FALSE;
}
-
/*************************************************
* Exim Daemon Mainline *
*************************************************/
/* Allocate enough pollstructs for inetd mode plus the ancillary sockets;
also used when there are no listen sockets. */
-fd_polls = store_get(sizeof(struct pollfd) * 3, FALSE);
+fd_polls = store_get(sizeof(struct pollfd) * 3, GET_UNTAINTED);
if (f.inetd_wait_mode)
{
sep = 0;
while ((s = string_nextinlist(&list, &sep, NULL, 0)))
pct++;
- default_smtp_port = store_get((pct+1) * sizeof(int), FALSE);
+ default_smtp_port = store_get((pct+1) * sizeof(int), GET_UNTAINTED);
list = daemon_smtp_port;
sep = 0;
for (pct = 0;
ipa->port = default_smtp_port[0];
for (int i = 1; default_smtp_port[i] > 0; i++)
{
- ip_address_item *new = store_get(sizeof(ip_address_item), FALSE);
+ ip_address_item * new = store_get(sizeof(ip_address_item), GET_UNTAINTED);
memcpy(new->address, ipa->address, Ustrlen(ipa->address) + 1);
new->port = default_smtp_port[i];
for (ipa = addresses; ipa; ipa = ipa->next)
listen_socket_count++;
fd_polls = store_get(sizeof(struct pollfd) * (listen_socket_count + 2),
- FALSE);
+ GET_UNTAINTED);
for (struct pollfd * p = fd_polls; p < fd_polls + listen_socket_count + 2;
p++)
{ p->fd = -1; p->events = POLLIN; }
if (smtp_accept_max > 0)
{
- smtp_slots = store_get(smtp_accept_max * sizeof(smtp_slot), FALSE);
+ smtp_slots = store_get(smtp_accept_max * sizeof(smtp_slot), GET_UNTAINTED);
for (int i = 0; i < smtp_accept_max; i++) smtp_slots[i] = empty_smtp_slot;
}
}
if (queue_interval > 0 && local_queue_run_max > 0)
{
- queue_pid_slots = store_get(local_queue_run_max * sizeof(pid_t), FALSE);
+ queue_pid_slots = store_get(local_queue_run_max * sizeof(pid_t), GET_UNTAINTED);
for (int i = 0; i < local_queue_run_max; i++) queue_pid_slots[i] = 0;
}