-
Notifications
You must be signed in to change notification settings - Fork 271
/
main.c
133 lines (114 loc) · 3.43 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/* Copyright (c) 2002-2017 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "array.h"
#include "ioloop.h"
#include "hostpid.h"
#include "abspath.h"
#include "restrict-access.h"
#include "fd-close-on-exec.h"
#include "anvil-client.h"
#include "master-service.h"
#include "master-service-settings.h"
#include "master-interface.h"
#include "mail-deliver.h"
#include "mail-storage-service.h"
#include "lda-settings.h"
#include "lmtp-settings.h"
#include "client.h"
#include "main.h"
#include <unistd.h>
#define DNS_CLIENT_SOCKET_PATH "dns-client"
#define LMTP_MASTER_FIRST_LISTEN_FD 3
#define IS_STANDALONE() \
(getenv(MASTER_IS_PARENT_ENV) == NULL)
const char *dns_client_socket_path, *base_dir;
struct mail_storage_service_ctx *storage_service;
struct anvil_client *anvil;
static void client_connected(struct master_service_connection *conn)
{
master_service_client_connection_accept(conn);
(void)client_create(conn->fd, conn->fd, conn);
}
static void drop_privileges(void)
{
struct restrict_access_settings set;
const char *error;
/* by default we don't drop any privileges, but keep running as root. */
restrict_access_get_env(&set);
/* open config connection before dropping privileges */
struct master_service_settings_input input;
struct master_service_settings_output output;
i_zero(&input);
input.module = "lmtp";
input.service = "lmtp";
if (master_service_settings_read(master_service,
&input, &output, &error) < 0)
i_fatal("Error reading configuration: %s", error);
restrict_access_by_env(NULL, FALSE);
}
static void main_init(void)
{
struct master_service_connection conn;
if (IS_STANDALONE()) {
i_zero(&conn);
(void)client_create(STDIN_FILENO, STDOUT_FILENO, &conn);
}
dns_client_socket_path = t_abspath(DNS_CLIENT_SOCKET_PATH);
mail_deliver_hooks_init();
}
static void main_deinit(void)
{
clients_destroy();
if (anvil != NULL)
anvil_client_deinit(&anvil);
}
int main(int argc, char *argv[])
{
const struct setting_parser_info *set_roots[] = {
&lda_setting_parser_info,
&lmtp_setting_parser_info,
NULL
};
enum master_service_flags service_flags =
MASTER_SERVICE_FLAG_USE_SSL_SETTINGS;
enum mail_storage_service_flags storage_service_flags =
MAIL_STORAGE_SERVICE_FLAG_DISALLOW_ROOT |
MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP |
MAIL_STORAGE_SERVICE_FLAG_NO_LOG_INIT |
MAIL_STORAGE_SERVICE_FLAG_NO_IDLE_TIMEOUT;
int c;
if (IS_STANDALONE()) {
service_flags |= MASTER_SERVICE_FLAG_STANDALONE |
MASTER_SERVICE_FLAG_STD_CLIENT;
} else {
service_flags |= MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN ;
}
master_service = master_service_init("lmtp", service_flags,
&argc, &argv, "D");
while ((c = master_getopt(master_service)) > 0) {
switch (c) {
case 'D':
storage_service_flags |=
MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS;
break;
default:
return FATAL_DEFAULT;
}
}
if (t_get_current_dir(&base_dir) < 0)
i_fatal("getcwd() failed: %m");
drop_privileges();
master_service_init_log(master_service,
t_strdup_printf("lmtp(%s): ", my_pid));
storage_service = mail_storage_service_init(master_service, set_roots,
storage_service_flags);
restrict_access_allow_coredumps(TRUE);
main_init();
master_service_init_finish(master_service);
master_service_run(master_service, client_connected);
main_deinit();
mail_storage_service_deinit(&storage_service);
master_service_deinit(&master_service);
return 0;
}