Cross Reference: /dovecot/src/pop3/main.c
main.c revision 43a2293a8bddfbeed84b29193c599071c44d17c7
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen/* Copyright (C) 2002-2003 Timo Sirainen */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "common.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "ioloop.h"
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include "network.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "lib-signals.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "restrict-access.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "fd-close-on-exec.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "process-title.h"
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen#include "randgen.h"
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen#include "module-dir.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include "mail-storage.h"
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include <stdio.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include <stdlib.h>
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen#include <unistd.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#include <syslog.h>
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#define IS_STANDALONE() \
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen (getenv("LOGGED_IN") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstruct client_workaround_list {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *name;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen enum client_workarounds num;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen};
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstruct client_workaround_list client_workaround_list[] = {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen { "outlook-no-nuls", WORKAROUND_OUTLOOK_NO_NULS },
43a2293a8bddfbeed84b29193c599071c44d17c7Timo Sirainen { "oe-ns-eoh", WORKAROUND_OE_NS_EOH },
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen { NULL, 0 }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen};
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstruct ioloop *ioloop;
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainenvoid (*hook_mail_storage_created)(struct mail_storage **storage) = NULL;
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainenvoid (*hook_client_created)(struct client **client) = NULL;
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainenstatic struct module *modules;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic char log_prefix[128]; /* syslog() needs this to be permanent */
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenenum client_workarounds client_workarounds = 0;
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainenint enable_last_command = FALSE;
9beca5d6e1f018a7851a57117c036540d823957fTimo Sirainenint no_flag_updates = FALSE;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void sig_quit(int signo __attr_unused__)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen io_loop_stop(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainenstatic void parse_workarounds(void)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen{
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen struct client_workaround_list *list;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen const char *env, *const *str;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen env = getenv("POP3_CLIENT_WORKAROUNDS");
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (env == NULL)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen return;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen for (str = t_strsplit_spaces(env, " "); *str != NULL; str++) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen list = client_workaround_list;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen for (; list->name != NULL; list++) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (strcasecmp(*str, list->name) == 0) {
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen client_workarounds |= list->num;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen break;
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen if (list->name == NULL)
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen i_fatal("Unknown client workaround: %s", *str);
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen }
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen}
fa45f3f1ad423381ba07056e415ffc4d6449f089Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void open_logfile(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen const char *user;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen if (getenv("LOG_TO_MASTER") != NULL) {
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen i_set_failure_internal();
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen return;
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen }
316dad8277db6575354eba30d3fc7a1c0447c513Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = getenv("USER");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (user == NULL) user = "??";
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (strlen(user) >= sizeof(log_prefix)-6) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* quite a long user name, cut it */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = t_strndup(user, sizeof(log_prefix)-6-2);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen user = t_strconcat(user, "..", NULL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_snprintf(log_prefix, sizeof(log_prefix), "pop3(%s)", user);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("USE_SYSLOG") != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_failure_syslog(log_prefix, LOG_NDELAY, LOG_MAIL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen else {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* log to file or stderr */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_failure_file(getenv("LOGFILE"), log_prefix);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("INFOLOGFILE") != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_info_file(getenv("INFOLOGFILE"));
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_set_failure_timestamp_format(getenv("LOGSTAMP"));
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void drop_privileges(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* Log file or syslog opening probably requires roots */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen open_logfile();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen /* Most likely needed. Have to open /dev/urandom before possible
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen chrooting. */
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen random_init();
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen restrict_access_by_env(!IS_STANDALONE());
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainenstatic int main_init(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen struct mail_storage *storage;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen const char *mail;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen lib_init_signals(sig_quit);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (getenv("USER") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("USER environment missing");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail_storage_register_all();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen modules = getenv("MODULE_DIR") == NULL ? NULL :
c0a05ba822189ff4f2c86645c38a5a904943192aTimo Sirainen module_dir_load(getenv("MODULE_DIR"), TRUE);
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = getenv("MAIL");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail == NULL) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* support also maildir-specific environment */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = getenv("MAILDIR");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail != NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen mail = t_strconcat("maildir:", mail, NULL);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen parse_workarounds();
a1fa538bac7e5f18d507446e84be49a163c6697dTimo Sirainen enable_last_command = getenv("POP3_ENABLE_LAST") != NULL;
9beca5d6e1f018a7851a57117c036540d823957fTimo Sirainen no_flag_updates = getenv("POP3_NO_FLAG_UPDATES") != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
84f80d9231b6ddc80ebfae425fd3674620fdf746Timo Sirainen storage = mail_storage_create_with_data(mail, getenv("USER"));
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (storage == NULL) {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* failed */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (mail != NULL && *mail != '\0')
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("Failed to create storage with data: %s", mail);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen else {
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen const char *home;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen home = getenv("HOME");
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (home == NULL) home = "not set";
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_fatal("MAIL environment missing and "
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen "autodetection failed (home %s)", home);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen }
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen if (hook_mail_storage_created != NULL)
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen hook_mail_storage_created(&storage);
8f1d14e3ada93a6d6ee64f73c6e6ae2364d8eba1Timo Sirainen
966e9213f116ae8423634433106b02c833d9376bTimo Sirainen return client_create(0, 1, storage) != NULL;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenstatic void main_deinit(void)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* warn about being killed because of some signal, except SIGINT (^C)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen which is too common at least while testing :) */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen if (lib_signal_kill != 0 && lib_signal_kill != 2)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen i_warning("Killed with signal %d", lib_signal_kill);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen module_dir_unload(modules);
9e708a17f984ef7690ff2468ec19ad62c95b1ac2Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen clients_deinit();
18d788657cff0fc3905b6a484d33c8c9fc2b9ebaTimo Sirainen mail_storage_deinit();
aa78a2506ee69a6bd58cc706210ee79b62ec0954Timo Sirainen random_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen closelog();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainenint main(int argc __attr_unused__, char *argv[], char *envp[])
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen{
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#ifdef DEBUG
b565c76999227da8db3670ec2f4b0c39690d8c40Timo Sirainen if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL)
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen fd_debug_verify_leaks(3, 1024);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen#endif
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen if (IS_STANDALONE() && getuid() == 0 &&
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen net_getpeername(1, NULL, NULL) == 0) {
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen printf("-ERR pop3 binary must not be started from "
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen "inetd, use pop3-login instead.\n");
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen return 1;
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen }
4dbe08e1f7f1271299ada9338ff5015367efd0b7Timo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen /* NOTE: we start rooted, so keep the code minimal until
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen restrict_access_by_env() is called */
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen lib_init();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen drop_privileges();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen process_title_init(argv, envp);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen ioloop = io_loop_create(system_pool);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainen if (main_init())
67b785ce2485243c490f0a8b0753ac4a5d347265Timo Sirainen io_loop_run(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen main_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen io_loop_destroy(ioloop);
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen lib_deinit();
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen return 0;
548f87789cf9865572b7b86f7be5a9bbfa132f3fTimo Sirainen}