~ubuntu-branches/ubuntu/utopic/dovecot/utopic-proposed

« back to all changes in this revision

Viewing changes to src/auth/auth-fields.c

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-01-08 09:35:49 UTC
  • mfrom: (4.1.35 sid)
  • Revision ID: package-import@ubuntu.com-20140108093549-i72o93pux8p0dlaf
Tags: 1:2.2.9-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/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.
  + Use the autotools-dev dh addon to update config.guess/config.sub for
    arm64.
* Dropped changes, included in Debian:
  - Update Dovecot name to reflect distribution in login greeting.
  - Update Drac plugin for >= 2.0.0 support.
* d/control: Drop dovecot-postfix package as its no longer required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005-2013 Dovecot authors, see the included COPYING file */
 
2
 
 
3
#include "auth-common.h"
 
4
#include "array.h"
 
5
#include "str.h"
 
6
#include "strescape.h"
 
7
#include "ostream.h"
 
8
#include "auth-request.h"
 
9
#include "auth-fields.h"
 
10
 
 
11
struct auth_fields {
 
12
        pool_t pool;
 
13
        ARRAY_TYPE(auth_field) fields, snapshot_fields;
 
14
        unsigned int snapshot_idx;
 
15
        bool snapshotted;
 
16
};
 
17
 
 
18
struct auth_fields *auth_fields_init(pool_t pool)
 
19
{
 
20
        struct auth_fields *fields;
 
21
 
 
22
        fields = p_new(pool, struct auth_fields, 1);
 
23
        fields->pool = pool;
 
24
        return fields;
 
25
}
 
26
 
 
27
static void auth_fields_snapshot_preserve(struct auth_fields *fields)
 
28
{
 
29
        if (!fields->snapshotted || array_is_created(&fields->snapshot_fields))
 
30
                return;
 
31
 
 
32
        p_array_init(&fields->snapshot_fields, fields->pool,
 
33
                     array_count(&fields->fields));
 
34
        array_append_array(&fields->snapshot_fields, &fields->fields);
 
35
}
 
36
 
 
37
static bool
 
38
auth_fields_find_idx(struct auth_fields *fields, const char *key,
 
39
                     unsigned int *idx_r)
 
40
{
 
41
        const struct auth_field *f;
 
42
        unsigned int i, count;
 
43
 
 
44
        if (!array_is_created(&fields->fields))
 
45
                return FALSE;
 
46
 
 
47
        f = array_get(&fields->fields, &count);
 
48
        for (i = 0; i < count; i++) {
 
49
                if (strcmp(f[i].key, key) == 0) {
 
50
                        *idx_r = i;
 
51
                        return TRUE;
 
52
                }
 
53
        }
 
54
        return FALSE;
 
55
}
 
56
 
 
57
void auth_fields_add(struct auth_fields *fields,
 
58
                     const char *key, const char *value,
 
59
                     enum auth_field_flags flags)
 
60
{
 
61
        struct auth_field *field;
 
62
        unsigned int idx;
 
63
 
 
64
        i_assert(*key != '\0');
 
65
        i_assert(strchr(key, '\t') == NULL &&
 
66
                 strchr(key, '\n') == NULL);
 
67
 
 
68
        if (!auth_fields_find_idx(fields, key, &idx)) {
 
69
                if (!array_is_created(&fields->fields))
 
70
                        p_array_init(&fields->fields, fields->pool, 16);
 
71
 
 
72
                field = array_append_space(&fields->fields);
 
73
                field->key = p_strdup(fields->pool, key);
 
74
        } else {
 
75
                auth_fields_snapshot_preserve(fields);
 
76
                field = array_idx_modifiable(&fields->fields, idx);
 
77
        }
 
78
        field->value = p_strdup_empty(fields->pool, value);
 
79
        field->flags = flags | AUTH_FIELD_FLAG_CHANGED;
 
80
}
 
81
 
 
82
void auth_fields_remove(struct auth_fields *fields, const char *key)
 
83
{
 
84
        unsigned int idx;
 
85
 
 
86
        if (auth_fields_find_idx(fields, key, &idx)) {
 
87
                auth_fields_snapshot_preserve(fields);
 
88
                array_delete(&fields->fields, idx, 1);
 
89
        }
 
90
}
 
91
 
 
92
const char *auth_fields_find(struct auth_fields *fields, const char *key)
 
93
{
 
94
        const struct auth_field *field;
 
95
        unsigned int idx;
 
96
 
 
97
        if (!auth_fields_find_idx(fields, key, &idx))
 
98
                return NULL;
 
99
 
 
100
        field = array_idx(&fields->fields, idx);
 
101
        return field->value == NULL ? "" : field->value;
 
102
}
 
103
 
 
104
bool auth_fields_exists(struct auth_fields *fields, const char *key)
 
105
{
 
106
        return auth_fields_find(fields, key) != NULL;
 
107
}
 
108
 
 
109
void auth_fields_reset(struct auth_fields *fields)
 
110
{
 
111
        if (array_is_created(&fields->fields)) {
 
112
                auth_fields_snapshot_preserve(fields);
 
113
                array_clear(&fields->fields);
 
114
        }
 
115
}
 
116
 
 
117
void auth_fields_import(struct auth_fields *fields, const char *str,
 
118
                        enum auth_field_flags flags)
 
119
{
 
120
        T_BEGIN {
 
121
                const char *const *arg = t_strsplit_tab(str);
 
122
                const char *key, *value;
 
123
 
 
124
                for (; *arg != NULL; arg++) {
 
125
                        value = strchr(*arg, '=');
 
126
                        if (value == NULL) {
 
127
                                key = *arg;
 
128
                                value = NULL;
 
129
                        } else {
 
130
                                key = t_strdup_until(*arg, value++);
 
131
                        }
 
132
                        auth_fields_add(fields, key, value, flags);
 
133
                }
 
134
        } T_END;
 
135
}
 
136
 
 
137
const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields)
 
138
{
 
139
        if (!array_is_created(&fields->fields))
 
140
                p_array_init(&fields->fields, fields->pool, 1);
 
141
        return &fields->fields;
 
142
}
 
143
 
 
144
void auth_fields_append(struct auth_fields *fields, string_t *dest,
 
145
                        enum auth_field_flags flags_mask,
 
146
                        enum auth_field_flags flags_result)
 
147
{
 
148
        const struct auth_field *f;
 
149
        unsigned int i, count;
 
150
        bool first = TRUE;
 
151
 
 
152
        if (!array_is_created(&fields->fields))
 
153
                return;
 
154
 
 
155
        f = array_get(&fields->fields, &count);
 
156
        for (i = 0; i < count; i++) {
 
157
                if ((f[i].flags & flags_mask) != flags_result)
 
158
                        continue;
 
159
 
 
160
                if (first)
 
161
                        first = FALSE;
 
162
                else
 
163
                        str_append_c(dest, '\t');
 
164
                str_append(dest, f[i].key);
 
165
                if (f[i].value != NULL) {
 
166
                        str_append_c(dest, '=');
 
167
                        str_append_tabescaped(dest, f[i].value);
 
168
                }
 
169
        }
 
170
}
 
171
 
 
172
bool auth_fields_is_empty(struct auth_fields *fields)
 
173
{
 
174
        return fields == NULL || !array_is_created(&fields->fields) ||
 
175
                array_count(&fields->fields) == 0;
 
176
}
 
177
 
 
178
void auth_fields_booleanize(struct auth_fields *fields, const char *key)
 
179
{
 
180
        struct auth_field *field;
 
181
        unsigned int idx;
 
182
 
 
183
        if (auth_fields_find_idx(fields, key, &idx)) {
 
184
                field = array_idx_modifiable(&fields->fields, idx);
 
185
                field->value = NULL;
 
186
        }
 
187
}
 
188
 
 
189
void auth_fields_snapshot(struct auth_fields *fields)
 
190
{
 
191
        struct auth_field *field;
 
192
 
 
193
        fields->snapshotted = TRUE;
 
194
        if (!array_is_created(&fields->fields))
 
195
                return;
 
196
 
 
197
        if (!array_is_created(&fields->snapshot_fields)) {
 
198
                /* try to avoid creating this array */
 
199
                fields->snapshot_idx = array_count(&fields->fields);
 
200
        } else {
 
201
                array_clear(&fields->snapshot_fields);
 
202
                array_append_array(&fields->snapshot_fields, &fields->fields);
 
203
        }
 
204
        array_foreach_modifiable(&fields->fields, field)
 
205
                field->flags &= ~AUTH_FIELD_FLAG_CHANGED;
 
206
}
 
207
 
 
208
void auth_fields_rollback(struct auth_fields *fields)
 
209
{
 
210
        if (array_is_created(&fields->snapshot_fields)) {
 
211
                array_clear(&fields->fields);
 
212
                array_append_array(&fields->fields, &fields->snapshot_fields);
 
213
        } else if (array_is_created(&fields->fields)) {
 
214
                array_delete(&fields->fields, fields->snapshot_idx,
 
215
                             array_count(&fields->fields) -
 
216
                             fields->snapshot_idx);
 
217
        }
 
218
}