42
43
unsigned int imap_max_line_length;
43
44
enum client_workarounds client_workarounds = 0;
44
45
const char *logout_format;
46
const char *imap_id_send, *imap_id_log;
46
48
static struct io *log_io = NULL;
47
49
static struct module *modules = NULL;
48
50
static char log_prefix[128]; /* syslog() needs this to be permanent */
49
static pool_t namespace_pool;
51
52
void (*hook_client_created)(struct client **client) = NULL;
53
54
string_t *capability_string;
55
static void sig_die(int signo, void *context ATTR_UNUSED)
56
static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
57
58
/* warn about being killed because of some signal, except SIGINT (^C)
58
59
which is too common at least while testing :) */
60
i_warning("Killed with signal %d", signo);
60
if (si->si_signo != SIGINT) {
61
i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
62
si->si_signo, dec2str(si->si_pid),
64
lib_signal_code_to_str(si->si_signo, si->si_code));
61
66
io_loop_stop(ioloop);
64
69
static void log_error_callback(void *context ATTR_UNUSED)
71
/* the log fd is closed, don't die when trying to log later */
72
i_set_failure_ignore_errors(TRUE);
66
74
io_loop_stop(ioloop);
143
151
/* Log file or syslog opening probably requires roots */
146
/* Most likely needed. Have to open /dev/urandom before possible
150
154
/* Load the plugins before chrooting. Their init() is called later. */
151
155
if (getenv("MAIL_PLUGINS") != NULL) {
152
156
const char *plugin_dir = getenv("MAIL_PLUGIN_DIR");
160
164
restrict_access_by_env(!IS_STANDALONE());
165
restrict_access_allow_coredumps(TRUE);
163
168
static void main_init(void)
165
170
struct client *client;
166
struct mail_namespace *ns;
167
const char *user, *str;
171
struct ostream *output;
172
struct mail_user *user;
173
const char *username, *home, *str, *tag;
169
175
lib_signals_init();
170
176
lib_signals_set_handler(SIGINT, TRUE, sig_die, NULL);
172
178
lib_signals_ignore(SIGPIPE, TRUE);
173
179
lib_signals_ignore(SIGALRM, FALSE);
175
user = getenv("USER");
181
username = getenv("USER");
182
if (username == NULL && IS_STANDALONE())
183
username = getlogin();
184
if (username == NULL) {
185
if (getenv("DOVECOT_MASTER") == NULL)
180
186
i_fatal("USER environment missing");
188
i_fatal("login_executable setting must be imap-login, "
193
home = getenv("HOME");
183
194
if (getenv("DEBUG") != NULL) {
186
home = getenv("HOME");
187
195
i_info("Effective uid=%s, gid=%s, home=%s",
188
196
dec2str(geteuid()), dec2str(getegid()),
189
197
home != NULL ? home : "(none)");
198
206
capability_string = str_new(default_pool, sizeof(CAPABILITY_STRING)+32);
199
207
str_append(capability_string, CAPABILITY_STRING);
201
dict_driver_register(&dict_driver_client);
209
dict_drivers_register_builtin();
210
mail_users_init(getenv("AUTH_SOCKET_PATH"), getenv("DEBUG") != NULL);
202
211
mail_storage_init();
203
212
mail_storage_register_all();
204
213
mailbox_list_register_all();
216
imap_fetch_handlers_init();
208
218
module_dir_init(modules);
228
238
if (logout_format == NULL)
229
239
logout_format = "bytes=%i/%o";
241
imap_id_send = getenv("IMAP_ID_SEND");
242
imap_id_log = getenv("IMAP_ID_LOG");
231
244
parse_workarounds();
233
namespace_pool = pool_alloconly_create("namespaces", 1024);
234
if (mail_namespaces_init(namespace_pool, user, &ns) < 0)
246
user = mail_user_init(username);
247
mail_user_set_home(user, home);
248
if (mail_namespaces_init(user) < 0)
235
249
i_fatal("Namespace initialization failed");
236
client = client_create(0, 1, ns);
238
o_stream_cork(client->output);
239
if (IS_STANDALONE()) {
250
client = client_create(0, 1, user);
252
output = client->output;
253
o_stream_ref(output);
254
o_stream_cork(output);
256
/* IMAPLOGINTAG environment is compatible with mailfront */
257
tag = getenv("IMAPLOGINTAG");
240
259
client_send_line(client, t_strconcat(
241
260
"* PREAUTH [CAPABILITY ",
242
261
str_c(capability_string), "] "
243
"Logged in as ", user, NULL));
244
} else if (getenv("IMAPLOGINTAG") != NULL) {
245
/* Support for mailfront */
246
client_send_line(client, t_strconcat(getenv("IMAPLOGINTAG"),
247
" OK Logged in.", NULL));
262
"Logged in as ", user->username, NULL));
264
client_send_line(client, t_strconcat(
265
tag, " OK [CAPABILITY ",
266
str_c(capability_string), "] Logged in", NULL));
249
o_stream_uncork(client->output);
268
str = getenv("CLIENT_INPUT");
269
if (str != NULL) T_BEGIN {
270
buffer_t *buf = t_base64_decode_str(str);
272
if (!i_stream_add_data(client->input, buf->data,
274
i_panic("Couldn't add client input to stream");
275
(void)client_handle_input(client);
278
o_stream_uncork(output);
279
o_stream_unref(&output);
252
282
static void main_deinit(void)
256
286
clients_deinit();
258
288
module_dir_unload(&modules);
289
imap_fetch_handlers_deinit();
259
290
commands_deinit();
260
mail_storage_deinit();
261
dict_driver_unregister(&dict_driver_client);
263
pool_unref(&namespace_pool);
291
mail_storage_deinit();
293
dict_drivers_unregister_builtin();
265
295
str_free(&capability_string);
271
301
int main(int argc ATTR_UNUSED, char *argv[], char *envp[])
274
if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL)
304
if (!IS_STANDALONE() && getenv("GDB") == NULL)
275
305
fd_debug_verify_leaks(3, 1024);
277
307
if (IS_STANDALONE() && getuid() == 0 &&
289
319
process_title_init(argv, envp);
290
320
ioloop = io_loop_create();
322
/* fake that we're running, so we know if client was destroyed
323
while initializing */
324
io_loop_set_running(ioloop);
326
if (io_loop_is_running(ioloop))
296
330
io_loop_destroy(&ioloop);