~ubuntu-branches/ubuntu/wily/dovecot/wily

« back to all changes in this revision

Viewing changes to src/imap/main.c

  • Committer: Bazaar Package Importer
  • Author(s): CHuck Short, Chuck Short
  • Date: 2009-11-06 00:47:29 UTC
  • mfrom: (4.1.9 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091106004729-i39n7v9e7d4h51f6
Tags: 1:1.2.6-1ubuntu1
* Merge from debian testing, remaining changes:
  Add new binary pkg dovecot-postfix that integrates postfix and dovecot
  automatically: (LP: #164837)
  + debian/control:
    - add new binary with short description
    - set Architecture all for dovecot-postfix (LP: #329878)
  + debian/dovecot-postfix.postinst:
    - create initial certificate symlinks to snakeoil.
    - set up postfix with postconf to:
      - use Maildir/ as the default mailbox.
      - use dovecot as the sasl authentication server.
      - use dovecot LDA (deliver).
      - use tls for smtp{d} services.
    - fix certificates paths in postfix' main.cf
    - add reject_unauth_destination to postfix' recipient restrictions
    - add reject_unknown_sender_domain to postfix' sender restrictions
    - rename configuration name on remove, delete on purge
    - restart dovecot after linking certificates
    - handle use case when postfix is unconfigurated
   + debian/dovecot-postfix.dirs: create backup directory for postfix's configuration
   + restart postfix and dovecot.
   + debian/dovecot-postfix.postrm:
     - remove all dovecot related configuration from postfix.
     - restart postfix and dovecot.
   + debian/dovecot-common.init:
     - check if /etc/dovecot/dovecot-postfix.conf exists and use it
       as the configuration file if so.
   + debian/patches/warning-ubuntu-postfix.dpatch
     - add warning about dovecot-postfix.conf in dovecot default 
       configuration file
   + debian/patches/dovecot-postfix.conf.diff:
     - Ubuntu server custom changes to the default dovecot configuration for
       better interfation with postfix
     - enable sieve plugin
   + debian/patches/dovecot-postfix.conf.diff:
     + Ubuntu server custom changes to the default dovecot configuration for
       better integration with postfix:
       - enable imap, pop3, imaps, pop3s and managesieve by default.
       - enable dovecot LDA (deliver).
       - enable SASL auth socket in postfix private directory.
   + debian/rules:
     - copy, patch and install dovecot-postfix.conf in /etc/dovecot/.
     - build architecure independent packages too
   + Use Snakeoil SSL certificates by default.
     - debian/control: Depend on ssl-cert.
     - debian/patches/ssl-cert-snakeoil.dpatch: Change default SSL cert
       paths to snakeoil.
     - debian/dovecot-common.postinst: Relax grep for SSL_* a bit.
   + Add autopkgtest to debian/tests/*.
   + Fast TearDown: Update the lsb init header to not stop in level 6.
   + Add ufw integration:
     - Created debian/dovecot-common.ufw.profile.
     - debian/rules:
       + install profile
     - debian/control:
       + Suggest ufw
   + debian/{control,rules}: enable PIE hardening.
   + dovecot-imapd, dovecot-pop3: Replaces dovecot-common (<< 1:1.1). LP: #254721
   + debian/control:
     - Update Vcs-* headers.
   + debian/rules:
     - Create emtpy stamp.h.in files in dovecot-sieve/ and dovecot-managesieve/
       if they're not there since empty files are not included in the diff.gz 
       file.
   + Add SMTP-AUTH support for Outlook (login auth mechanism)
   + Dropped:
     - debian/patches/security-CVE-2009-3235: Applied upstream.
     - debian/patches/fix-pop3-assertion.dpatch: Applied upstream.
     - dovecot-sieve and dovecot-managesieve: Use the debian patches instead.

  [Chuck Short]
  - Updated dovecot-sieve to 0.1.13.
  - Updated dovecot-managesieve to 0.11.9.

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
#include "network.h"
6
6
#include "ostream.h"
7
7
#include "str.h"
 
8
#include "base64.h"
 
9
#include "istream.h"
8
10
#include "lib-signals.h"
9
11
#include "restrict-access.h"
10
12
#include "fd-close-on-exec.h"
11
13
#include "process-title.h"
12
 
#include "randgen.h"
13
14
#include "module-dir.h"
14
 
#include "dict-client.h"
 
15
#include "dict.h"
15
16
#include "mail-storage.h"
16
17
#include "commands.h"
 
18
#include "imap-fetch.h"
17
19
#include "mail-namespace.h"
18
 
#include "imap-thread.h"
19
20
 
20
21
#include <stdio.h>
21
22
#include <stdlib.h>
23
24
#include <syslog.h>
24
25
 
25
26
#define IS_STANDALONE() \
26
 
        (getenv("LOGGED_IN") == NULL && getenv("IMAPLOGINTAG") == NULL)
 
27
        (getenv("IMAPLOGINTAG") == NULL)
27
28
 
28
29
struct client_workaround_list {
29
30
        const char *name;
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;
45
47
 
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;
50
51
 
51
52
void (*hook_client_created)(struct client **client) = NULL;
52
53
 
53
54
string_t *capability_string;
54
55
 
55
 
static void sig_die(int signo, void *context ATTR_UNUSED)
 
56
static void sig_die(const siginfo_t *si, void *context ATTR_UNUSED)
56
57
{
57
58
        /* warn about being killed because of some signal, except SIGINT (^C)
58
59
           which is too common at least while testing :) */
59
 
        if (signo != SIGINT)
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),
 
63
                          dec2str(si->si_uid),
 
64
                          lib_signal_code_to_str(si->si_signo, si->si_code));
 
65
        }
61
66
        io_loop_stop(ioloop);
62
67
}
63
68
 
64
69
static void log_error_callback(void *context ATTR_UNUSED)
65
70
{
 
71
        /* the log fd is closed, don't die when trying to log later */
 
72
        i_set_failure_ignore_errors(TRUE);
 
73
 
66
74
        io_loop_stop(ioloop);
67
75
}
68
76
 
143
151
        /* Log file or syslog opening probably requires roots */
144
152
        open_logfile();
145
153
 
146
 
        /* Most likely needed. Have to open /dev/urandom before possible
147
 
           chrooting. */
148
 
        random_init();
149
 
 
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");
158
162
        }
159
163
 
160
164
        restrict_access_by_env(!IS_STANDALONE());
 
165
        restrict_access_allow_coredumps(TRUE);
161
166
}
162
167
 
163
168
static void main_init(void)
164
169
{
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;
168
174
 
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);
174
180
 
175
 
        user = getenv("USER");
176
 
        if (user == NULL) {
177
 
                if (IS_STANDALONE())
178
 
                        user = getlogin();
179
 
                if (user == NULL)
 
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");
 
187
                else {
 
188
                        i_fatal("login_executable setting must be imap-login, "
 
189
                                "not imap");
 
190
                }
181
191
        }
182
192
 
 
193
        home = getenv("HOME");
183
194
        if (getenv("DEBUG") != NULL) {
184
 
                const char *home;
185
 
 
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);
200
208
 
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();
205
214
        clients_init();
206
215
        commands_init();
 
216
        imap_fetch_handlers_init();
207
217
 
208
218
        module_dir_init(modules);
209
219
 
228
238
        if (logout_format == NULL)
229
239
                logout_format = "bytes=%i/%o";
230
240
 
 
241
        imap_id_send = getenv("IMAP_ID_SEND");
 
242
        imap_id_log = getenv("IMAP_ID_LOG");
 
243
 
231
244
        parse_workarounds();
232
245
 
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);
237
 
 
238
 
        o_stream_cork(client->output);
239
 
        if (IS_STANDALONE()) {
 
250
        client = client_create(0, 1, user);
 
251
 
 
252
        output = client->output;
 
253
        o_stream_ref(output);
 
254
        o_stream_cork(output);
 
255
 
 
256
        /* IMAPLOGINTAG environment is compatible with mailfront */
 
257
        tag = getenv("IMAPLOGINTAG");
 
258
        if (tag == NULL) {
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));
 
263
        } else {
 
264
                client_send_line(client, t_strconcat(
 
265
                        tag, " OK [CAPABILITY ",
 
266
                        str_c(capability_string), "] Logged in", NULL));
248
267
        }
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);
 
271
                if (buf->used > 0) {
 
272
                        if (!i_stream_add_data(client->input, buf->data,
 
273
                                               buf->used))
 
274
                                i_panic("Couldn't add client input to stream");
 
275
                        (void)client_handle_input(client);
 
276
                }
 
277
        } T_END;
 
278
        o_stream_uncork(output);
 
279
        o_stream_unref(&output);
250
280
}
251
281
 
252
282
static void main_deinit(void)
256
286
        clients_deinit();
257
287
 
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);
262
 
        random_deinit();
263
 
        pool_unref(&namespace_pool);
 
291
        mail_storage_deinit();
 
292
        mail_users_deinit();
 
293
        dict_drivers_unregister_builtin();
264
294
 
265
295
        str_free(&capability_string);
266
296
 
271
301
int main(int argc ATTR_UNUSED, char *argv[], char *envp[])
272
302
{
273
303
#ifdef DEBUG
274
 
        if (getenv("LOGGED_IN") != NULL && getenv("GDB") == NULL)
 
304
        if (!IS_STANDALONE() && getenv("GDB") == NULL)
275
305
                fd_debug_verify_leaks(3, 1024);
276
306
#endif
277
307
        if (IS_STANDALONE() && getuid() == 0 &&
289
319
        process_title_init(argv, envp);
290
320
        ioloop = io_loop_create();
291
321
 
 
322
        /* fake that we're running, so we know if client was destroyed
 
323
           while initializing */
 
324
        io_loop_set_running(ioloop);
292
325
        main_init();
293
 
        io_loop_run(ioloop);
 
326
        if (io_loop_is_running(ioloop))
 
327
                io_loop_run(ioloop);
294
328
        main_deinit();
295
329
 
296
330
        io_loop_destroy(&ioloop);