1
/* Copyright (c) 2005-2013 Dovecot authors, see the included COPYING file */
3
#include "auth-common.h"
8
#include "auth-request.h"
9
#include "auth-fields.h"
13
ARRAY_TYPE(auth_field) fields, snapshot_fields;
14
unsigned int snapshot_idx;
18
struct auth_fields *auth_fields_init(pool_t pool)
20
struct auth_fields *fields;
22
fields = p_new(pool, struct auth_fields, 1);
27
static void auth_fields_snapshot_preserve(struct auth_fields *fields)
29
if (!fields->snapshotted || array_is_created(&fields->snapshot_fields))
32
p_array_init(&fields->snapshot_fields, fields->pool,
33
array_count(&fields->fields));
34
array_append_array(&fields->snapshot_fields, &fields->fields);
38
auth_fields_find_idx(struct auth_fields *fields, const char *key,
41
const struct auth_field *f;
42
unsigned int i, count;
44
if (!array_is_created(&fields->fields))
47
f = array_get(&fields->fields, &count);
48
for (i = 0; i < count; i++) {
49
if (strcmp(f[i].key, key) == 0) {
57
void auth_fields_add(struct auth_fields *fields,
58
const char *key, const char *value,
59
enum auth_field_flags flags)
61
struct auth_field *field;
64
i_assert(*key != '\0');
65
i_assert(strchr(key, '\t') == NULL &&
66
strchr(key, '\n') == NULL);
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);
72
field = array_append_space(&fields->fields);
73
field->key = p_strdup(fields->pool, key);
75
auth_fields_snapshot_preserve(fields);
76
field = array_idx_modifiable(&fields->fields, idx);
78
field->value = p_strdup_empty(fields->pool, value);
79
field->flags = flags | AUTH_FIELD_FLAG_CHANGED;
82
void auth_fields_remove(struct auth_fields *fields, const char *key)
86
if (auth_fields_find_idx(fields, key, &idx)) {
87
auth_fields_snapshot_preserve(fields);
88
array_delete(&fields->fields, idx, 1);
92
const char *auth_fields_find(struct auth_fields *fields, const char *key)
94
const struct auth_field *field;
97
if (!auth_fields_find_idx(fields, key, &idx))
100
field = array_idx(&fields->fields, idx);
101
return field->value == NULL ? "" : field->value;
104
bool auth_fields_exists(struct auth_fields *fields, const char *key)
106
return auth_fields_find(fields, key) != NULL;
109
void auth_fields_reset(struct auth_fields *fields)
111
if (array_is_created(&fields->fields)) {
112
auth_fields_snapshot_preserve(fields);
113
array_clear(&fields->fields);
117
void auth_fields_import(struct auth_fields *fields, const char *str,
118
enum auth_field_flags flags)
121
const char *const *arg = t_strsplit_tab(str);
122
const char *key, *value;
124
for (; *arg != NULL; arg++) {
125
value = strchr(*arg, '=');
130
key = t_strdup_until(*arg, value++);
132
auth_fields_add(fields, key, value, flags);
137
const ARRAY_TYPE(auth_field) *auth_fields_export(struct auth_fields *fields)
139
if (!array_is_created(&fields->fields))
140
p_array_init(&fields->fields, fields->pool, 1);
141
return &fields->fields;
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)
148
const struct auth_field *f;
149
unsigned int i, count;
152
if (!array_is_created(&fields->fields))
155
f = array_get(&fields->fields, &count);
156
for (i = 0; i < count; i++) {
157
if ((f[i].flags & flags_mask) != flags_result)
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);
172
bool auth_fields_is_empty(struct auth_fields *fields)
174
return fields == NULL || !array_is_created(&fields->fields) ||
175
array_count(&fields->fields) == 0;
178
void auth_fields_booleanize(struct auth_fields *fields, const char *key)
180
struct auth_field *field;
183
if (auth_fields_find_idx(fields, key, &idx)) {
184
field = array_idx_modifiable(&fields->fields, idx);
189
void auth_fields_snapshot(struct auth_fields *fields)
191
struct auth_field *field;
193
fields->snapshotted = TRUE;
194
if (!array_is_created(&fields->fields))
197
if (!array_is_created(&fields->snapshot_fields)) {
198
/* try to avoid creating this array */
199
fields->snapshot_idx = array_count(&fields->fields);
201
array_clear(&fields->snapshot_fields);
202
array_append_array(&fields->snapshot_fields, &fields->fields);
204
array_foreach_modifiable(&fields->fields, field)
205
field->flags &= ~AUTH_FIELD_FLAG_CHANGED;
208
void auth_fields_rollback(struct auth_fields *fields)
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);