~james-page/ubuntu/raring/dovecot/autopkgtest

« back to all changes in this revision

Viewing changes to src/lib-storage/mail-user.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-06-11 11:11:54 UTC
  • mfrom: (1.15.2) (4.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120611111154-678cwbdj6ktgsv1h
Tags: 1:2.1.7-1ubuntu1
* Merge from Debian unstable, remaining changes:
  + Add mail-stack-delivery package:
    - Update d/rules
    - d/control: convert existing dovecot-postfix package to a dummy
      package and add new mail-stack-delivery package.
    - Update maintainer scripts.
    - Rename d/dovecot-postfix.* to debian/mail-stack-delivery.*
    - d/mail-stack-delivery.preinst: Move previously installed backups and
      config files to a new package namespace.
    - d/mail-stack-delivery.prerm: Added to handle downgrades.
  + Use Snakeoil SSL certificates by default:
    - d/control: Depend on ssl-cert.
    - d/dovecot-core.postinst: Relax grep for SSL_* a bit.
  + Add autopkgtest to debian/tests/*.
  + Add ufw integration:
    - d/dovecot-core.ufw.profile: new ufw profile.
    - d/rules: install profile in dovecot-core.
    - d/control: dovecot-core - suggest ufw.
  + d/{control,rules}: enable PIE hardening.
  + d/dovecot-core.dirs: Added usr/share/doc/dovecot-core
  + Add apport hook:
    - d/rules, d/source_dovecot.py
  + Add upstart job:
    - d/rules, d/dovecot-core.dovecot.upstart, d/control,
      d/dovecot-core.dirs, dovecot-imapd.{postrm, postinst, prerm},
      d/dovecot-pop3d.{postinst, postrm, prerm}.
      d/mail-stack-deliver.postinst: Convert init script to upstart.
  + d/control: Added Pre-Depends: dpkg (>= 1.15.6) to dovecot-dbg to support
    xz compression in Ubuntu.
  + d/control: Demote dovecot-common Recommends: to Suggests: to prevent
    install of extra packages on upgrade.
  + d/patches/dovecot-drac.patch: Updated with version for dovecot >= 2.0.0.
  + d/control: Drop B-D on systemd.
* Dropped changes:
  + d/patches/fix-racey-restart.patch: part of 2.1.x, no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2008-2011 Dovecot authors, see the included COPYING file */
 
1
/* Copyright (c) 2008-2012 Dovecot authors, see the included COPYING file */
2
2
 
3
3
#include "lib.h"
4
4
#include "array.h"
12
12
#include "settings-parser.h"
13
13
#include "auth-master.h"
14
14
#include "master-service.h"
 
15
#include "mountpoint-list.h"
15
16
#include "mail-storage-settings.h"
16
17
#include "mail-storage-private.h"
17
18
#include "mail-namespace.h"
26
27
static void mail_user_deinit_base(struct mail_user *user)
27
28
{
28
29
        mail_namespaces_deinit(&user->namespaces);
29
 
        pool_unref(&user->pool);
 
30
        if (user->mountpoints != NULL)
 
31
                mountpoint_list_deinit(&user->mountpoints);
30
32
}
31
33
 
32
34
struct mail_user *mail_user_alloc(const char *username,
48
50
        user->set_info = set_info;
49
51
        user->unexpanded_set = settings_dup(set_info, set, pool);
50
52
        user->set = settings_dup(set_info, set, pool);
 
53
        user->service = master_service_get_name(master_service);
51
54
 
52
55
        /* check settings so that the duplicated structure will again
53
56
           contain the parsed fields */
93
96
{
94
97
        const struct mail_storage_settings *mail_set;
95
98
        const char *home, *key, *value;
96
 
 
97
 
        if (user->_home == NULL &&
98
 
            settings_vars_have_key(user->set_info, user->set,
99
 
                                   'h', "home", &key, &value) &&
100
 
            mail_user_get_home(user, &home) <= 0) {
 
99
        bool need_home_dir;
 
100
 
 
101
        need_home_dir = user->_home == NULL &&
 
102
                settings_vars_have_key(user->set_info, user->set,
 
103
                                       'h', "home", &key, &value);
 
104
 
 
105
        /* expand mail_home setting before calling mail_user_get_home() */
 
106
        settings_var_expand(user->set_info, user->set,
 
107
                            user->pool, mail_user_var_expand_table(user));
 
108
 
 
109
        if (need_home_dir && mail_user_get_home(user, &home) <= 0) {
101
110
                *error_r = t_strdup_printf(
102
111
                        "userdb didn't return a home directory, "
103
112
                        "but %s used it (%%h): %s", key, value);
104
113
                return -1;
105
114
        }
106
115
 
107
 
        settings_var_expand(user->set_info, user->set,
108
 
                            user->pool, mail_user_var_expand_table(user));
109
116
        if (mail_user_expand_plugins_envs(user, error_r) < 0)
110
117
                return -1;
111
118
 
136
143
        i_assert(user->refcount > 0);
137
144
 
138
145
        *_user = NULL;
139
 
        if (--user->refcount == 0)
140
 
                user->v.deinit(user);
 
146
        if (user->refcount > 1) {
 
147
                user->refcount--;
 
148
                return;
 
149
        }
 
150
 
 
151
        /* call deinit() with refcount=1, otherwise we may assert-crash in
 
152
           mail_user_ref() that is called by some deinit() handler. */
 
153
        user->v.deinit(user);
 
154
        i_assert(user->refcount == 1);
 
155
        pool_unref(&user->pool);
141
156
}
142
157
 
143
158
struct mail_user *mail_user_find(struct mail_user *user, const char *name)
151
166
        return NULL;
152
167
}
153
168
 
154
 
void mail_user_set_vars(struct mail_user *user, uid_t uid, const char *service,
 
169
void mail_user_set_vars(struct mail_user *user, const char *service,
155
170
                        const struct ip_addr *local_ip,
156
171
                        const struct ip_addr *remote_ip)
157
172
{
158
 
        user->uid = uid;
 
173
        i_assert(service != NULL);
 
174
 
159
175
        user->service = p_strdup(user->pool, service);
160
176
        if (local_ip != NULL && local_ip->family != 0) {
161
177
                user->local_ip = p_new(user->pool, struct ip_addr, 1);
180
196
                { 'r', NULL, "rip" },
181
197
                { 'p', NULL, "pid" },
182
198
                { 'i', NULL, "uid" },
 
199
                { '\0', NULL, "gid" },
183
200
                { '\0', NULL, NULL }
184
201
        };
185
202
        struct var_expand_table *tab;
202
219
                p_strdup(user->pool, net_ip2addr(user->remote_ip));
203
220
        tab[7].value = my_pid;
204
221
        tab[8].value = p_strdup(user->pool, dec2str(user->uid));
 
222
        tab[9].value = p_strdup(user->pool, dec2str(user->gid));
205
223
 
206
224
        user->var_expand_table = tab;
207
225
        return user->var_expand_table;
251
269
        return path;
252
270
}
253
271
 
254
 
int mail_user_get_home(struct mail_user *user, const char **home_r)
 
272
static int mail_user_userdb_lookup_home(struct mail_user *user)
255
273
{
256
274
        struct auth_user_info info;
257
275
        struct auth_user_reply reply;
259
277
        const char *username, *const *fields;
260
278
        int ret;
261
279
 
 
280
        i_assert(!user->home_looked_up);
 
281
 
262
282
        memset(&info, 0, sizeof(info));
263
 
        info.service = "lib-storage";
 
283
        info.service = user->service;
264
284
        if (user->local_ip != NULL)
265
285
                info.local_ip = *user->local_ip;
266
286
        if (user->remote_ip != NULL)
267
287
                info.remote_ip = *user->remote_ip;
268
288
 
269
 
        if (user->home_looked_up) {
270
 
                *home_r = user->_home;
271
 
                return user->_home != NULL ? 1 : 0;
272
 
        }
273
 
        *home_r = NULL;
274
 
 
275
289
        if (mail_user_auth_master_conn == NULL)
276
290
                return 0;
277
291
 
279
293
        ret = auth_master_user_lookup(mail_user_auth_master_conn,
280
294
                                      user->username, &info, userdb_pool,
281
295
                                      &username, &fields);
282
 
        if (ret >= 0) {
 
296
        if (ret > 0) {
283
297
                auth_user_fields_parse(fields, userdb_pool, &reply);
284
 
                user->_home = ret == 0 ? NULL :
285
 
                        p_strdup(user->pool, reply.home);
286
 
                user->home_looked_up = TRUE;
287
 
                ret = user->_home != NULL ? 1 : 0;
288
 
                *home_r = user->_home;
 
298
                user->_home = p_strdup(user->pool, reply.home);
289
299
        }
290
300
        pool_unref(&userdb_pool);
291
301
        return ret;
292
302
}
293
303
 
 
304
int mail_user_get_home(struct mail_user *user, const char **home_r)
 
305
{
 
306
        int ret;
 
307
 
 
308
        if (user->home_looked_up) {
 
309
                *home_r = user->_home;
 
310
                return user->_home != NULL ? 1 : 0;
 
311
        }
 
312
 
 
313
        ret = mail_user_userdb_lookup_home(user);
 
314
        if (ret < 0)
 
315
                return -1;
 
316
 
 
317
        if (ret > 0 && user->_home == NULL && *user->set->mail_home != '\0') {
 
318
                /* no home in userdb, fallback to mail_home setting */
 
319
                user->_home = user->set->mail_home;
 
320
        }
 
321
        user->home_looked_up = TRUE;
 
322
 
 
323
        *home_r = user->_home;
 
324
        return user->_home != NULL ? 1 : 0;
 
325
}
 
326
 
294
327
bool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module)
295
328
{
296
329
        const char *const *plugins;
329
362
{
330
363
        const char *home, *path = *pathp;
331
364
 
332
 
        if (mail_user_get_home(user, &home) < 0)
 
365
        if (*path != '~') {
 
366
                /* no need to expand home */
 
367
                return 0;
 
368
        }
 
369
 
 
370
        if (mail_user_get_home(user, &home) <= 0)
333
371
                return -1;
334
372
 
335
373
        path = home_expand_tilde(path, home);
356
394
        return t_strconcat(net_ip2addr(user->remote_ip), "/",
357
395
                           str_tabescape(user->username), NULL);
358
396
}
 
397
 
 
398
bool mail_user_is_path_mounted(struct mail_user *user, const char *path,
 
399
                               const char **error_r)
 
400
{
 
401
        struct mountpoint_list_rec *rec;
 
402
        const char *mounts_path;
 
403
 
 
404
        *error_r = NULL;
 
405
 
 
406
        if (user->mountpoints == NULL) {
 
407
                mounts_path = t_strdup_printf("%s/"MOUNTPOINT_LIST_FNAME,
 
408
                                              user->set->base_dir);
 
409
                user->mountpoints = mountpoint_list_init_readonly(mounts_path);
 
410
        } else {
 
411
                (void)mountpoint_list_refresh(user->mountpoints);
 
412
        }
 
413
        rec = mountpoint_list_find(user->mountpoints, path);
 
414
        if (rec == NULL || strcmp(rec->state, MOUNTPOINT_STATE_IGNORE) == 0) {
 
415
                /* we don't have any knowledge of this path's mountpoint.
 
416
                   assume it's fine. */
 
417
                return TRUE;
 
418
        }
 
419
        /* record exists for this mountpoint. see if it's mounted */
 
420
        if (mountpoint_list_update_mounted(user->mountpoints) == 0 &&
 
421
            !rec->mounted) {
 
422
                *error_r = t_strdup_printf("Mountpoint %s isn't mounted. "
 
423
                        "Mount it or remove it with doveadm mount remove",
 
424
                        rec->mount_path);
 
425
                return FALSE;
 
426
        }
 
427
        return TRUE;
 
428
}