~ubuntu-dev/ubuntu/lucid/dovecot/lucid-201002110912

« back to all changes in this revision

Viewing changes to src/login-common/master.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:
2
2
 
3
3
#include "common.h"
4
4
#include "hash.h"
 
5
#include "buffer.h"
5
6
#include "ioloop.h"
6
7
#include "network.h"
7
8
#include "fdpass.h"
23
24
static struct client destroyed_client;
24
25
 
25
26
static void client_call_master_callback(struct client *client,
26
 
                                        enum master_login_status status)
 
27
                                        const struct master_login_reply *reply)
27
28
{
28
29
        master_callback_t *master_callback;
29
30
 
31
32
        client->master_tag = 0;
32
33
        client->master_callback = NULL;
33
34
 
34
 
        master_callback(client, status);
 
35
        master_callback(client, reply);
35
36
}
36
37
 
37
38
static void request_handle(struct master_login_reply *reply)
45
46
                return;
46
47
        }
47
48
 
48
 
        client = hash_lookup(master_requests, POINTER_CAST(reply->tag));
 
49
        client = hash_table_lookup(master_requests, POINTER_CAST(reply->tag));
49
50
        if (client == NULL)
50
51
                i_fatal("Master sent reply with unknown tag %u", reply->tag);
51
52
 
52
 
        hash_remove(master_requests, POINTER_CAST(reply->tag));
 
53
        hash_table_remove(master_requests, POINTER_CAST(reply->tag));
53
54
        if (client != &destroyed_client) {
54
 
                client_call_master_callback(client, reply->status);
 
55
                client_call_master_callback(client, reply);
55
56
                /* NOTE: client may be destroyed now */
56
57
        }
57
58
}
59
60
void master_request_login(struct client *client, master_callback_t *callback,
60
61
                          unsigned int auth_pid, unsigned int auth_id)
61
62
{
62
 
        struct master_login_request req;
 
63
        buffer_t *buf;
 
64
        struct master_login_request *req;
63
65
        struct stat st;
 
66
        const unsigned char *data;
 
67
        size_t size;
 
68
        ssize_t ret;
 
69
        unsigned int cmd_tag_size;
64
70
 
65
71
        i_assert(auth_pid != 0);
66
72
 
67
73
        if (master_fd == -1) {
 
74
                struct master_login_reply reply;
 
75
 
68
76
                i_assert(closing_down);
69
 
                callback(client, MASTER_LOGIN_STATUS_INTERNAL_ERROR);
 
77
                memset(&reply, 0, sizeof(reply));
 
78
                reply.status = MASTER_LOGIN_STATUS_INTERNAL_ERROR;
 
79
                callback(client, &reply);
70
80
                return;
71
81
        }
72
82
 
73
 
        memset(&req, 0, sizeof(req));
74
 
        req.version = MASTER_LOGIN_PROTOCOL_VERSION;
75
 
        req.tag = ++master_tag_counter;
76
 
        if (req.tag == 0)
77
 
                req.tag = ++master_tag_counter;
78
 
        req.auth_pid = auth_pid;
79
 
        req.auth_id = auth_id;
80
 
        req.local_ip = client->local_ip;
81
 
        req.remote_ip = client->ip;
 
83
        data = i_stream_get_data(client->input, &size);
 
84
        cmd_tag_size = client->auth_command_tag == NULL ? 0 :
 
85
                strlen(client->auth_command_tag);
 
86
 
 
87
        buf = buffer_create_dynamic(pool_datastack_create(),
 
88
                                    sizeof(*req) + size + cmd_tag_size);
 
89
        buffer_write(buf, sizeof(*req), client->auth_command_tag, cmd_tag_size);
 
90
        buffer_write(buf, sizeof(*req) + cmd_tag_size, data, size);
 
91
        req = buffer_get_space_unsafe(buf, 0, sizeof(*req));
 
92
        req->version = MASTER_LOGIN_PROTOCOL_VERSION;
 
93
        req->tag = ++master_tag_counter;
 
94
        if (req->tag == 0)
 
95
                req->tag = ++master_tag_counter;
 
96
        req->auth_pid = auth_pid;
 
97
        req->auth_id = auth_id;
 
98
        req->local_ip = client->local_ip;
 
99
        req->remote_ip = client->ip;
 
100
        req->cmd_tag_size =  cmd_tag_size;
 
101
        req->data_size = req->cmd_tag_size + size;
 
102
#if (LOGIN_MAX_INBUF_SIZE*2) != MASTER_LOGIN_MAX_DATA_SIZE
 
103
#  error buffer max sizes unsynced
 
104
#endif
 
105
        i_assert(req->data_size <= LOGIN_MAX_INBUF_SIZE);
82
106
 
83
107
        if (fstat(client->fd, &st) < 0)
84
108
                i_fatal("fstat(client) failed: %m");
85
 
        req.ino = st.st_ino;
 
109
        req->ino = st.st_ino;
86
110
 
87
 
        if (fd_send(master_fd, client->fd, &req, sizeof(req)) != sizeof(req))
 
111
        ret = fd_send(master_fd, client->fd, buf->data, buf->used);
 
112
        if (ret < 0)
88
113
                i_fatal("fd_send(%d) failed: %m", client->fd);
 
114
        if ((size_t)ret != buf->used) {
 
115
                i_fatal("fd_send() sent only %d of %d bytes",
 
116
                        (int)ret, (int)buf->used);
 
117
        }
89
118
 
90
 
        client->master_tag = req.tag;
 
119
        client->master_tag = req->tag;
91
120
        client->master_callback = callback;
92
121
 
93
 
        hash_insert(master_requests, POINTER_CAST(req.tag), client);
 
122
        hash_table_insert(master_requests, POINTER_CAST(req->tag), client);
94
123
}
95
124
 
96
125
void master_request_abort(struct client *client)
97
126
{
 
127
        struct master_login_reply reply;
 
128
 
98
129
        /* we're still going to get the reply from the master, so just
99
130
           remember that we want to ignore it */
100
 
        hash_update(master_requests, POINTER_CAST(client->master_tag),
101
 
                    &destroyed_client);
 
131
        hash_table_update(master_requests, POINTER_CAST(client->master_tag),
 
132
                          &destroyed_client);
102
133
 
103
 
        client_call_master_callback(client, MASTER_LOGIN_STATUS_INTERNAL_ERROR);
 
134
        memset(&reply, 0, sizeof(reply));
 
135
        reply.status = MASTER_LOGIN_STATUS_INTERNAL_ERROR;
 
136
        client_call_master_callback(client, &reply);
104
137
}
105
138
 
106
139
void master_notify_state_change(enum master_login_state state)
262
295
        main_ref();
263
296
 
264
297
        master_fd = fd;
265
 
        master_requests = hash_create(system_pool, system_pool,
266
 
                                      0, NULL, NULL);
 
298
        master_requests = hash_table_create(system_pool, system_pool,
 
299
                                            0, NULL, NULL);
267
300
 
268
301
        master_pos = 0;
269
302
        io_master = io_add(master_fd, IO_READ, master_input, NULL);
271
304
 
272
305
void master_deinit(void)
273
306
{
274
 
        hash_destroy(&master_requests);
 
307
        hash_table_destroy(&master_requests);
275
308
 
276
309
        if (io_master != NULL)
277
310
                io_remove(&io_master);