1 #ifndef MAIL_USER_H
2 #define MAIL_USER_H
3
4 #include "net.h"
5 #include "unichar.h"
6 #include "mail-storage-settings.h"
7
8 struct module;
9 struct stats;
10 struct fs_settings;
11 struct ssl_iostream_settings;
12 struct mail_user;
13 struct dict_op_settings;
14
15 struct mail_user_vfuncs {
16 void (*deinit)(struct mail_user *user);
17 void (*deinit_pre)(struct mail_user *user);
18 void (*stats_fill)(struct mail_user *user, struct stats *stats);
19 };
20
21 struct mail_user_connection_data {
22 struct ip_addr *local_ip, *remote_ip;
23 in_port_t local_port, remote_port;
24
25 bool secured:1;
26 bool ssl_secured:1;
27 };
28
29 struct mail_user {
30 pool_t pool;
31 struct mail_user_vfuncs v, *vlast;
32 int refcount;
33
34 struct event *event;
35 /* User's creator if such exists. For example for autocreated shared
36 mailbox users their creator is the logged in user. */
37 struct mail_user *creator;
38 /* Set if user was created via mail_storage_service. */
39 struct mail_storage_service_user *_service_user;
40
41 const char *username;
42 /* don't access the home directly. It may be set lazily. */
43 const char *_home;
44
45 uid_t uid;
46 gid_t gid;
47 const char *service;
48 const char *session_id;
49 struct mail_user_connection_data conn;
50 const char *auth_mech, *auth_token, *auth_user;
51 const char *const *userdb_fields;
52 /* Timestamp when this session was initially created. Most importantly
53 this stays the same after IMAP client is hibernated and restored. */
54 time_t session_create_time;
55
56 const struct var_expand_table *var_expand_table;
57 /* If non-NULL, fail the user initialization with this error.
58 This could be set by plugins that need to fail the initialization. */
59 const char *error;
60
61 const struct setting_parser_info *set_info;
62 const struct mail_user_settings *unexpanded_set;
63 struct mail_user_settings *set;
64 struct mail_namespace *namespaces;
65 struct mail_storage *storages;
66 struct dict_op_settings *dict_op_set;
67 ARRAY(const struct mail_storage_hooks *) hooks;
68
69 normalizer_func_t *default_normalizer;
70 /* Filled lazily by mailbox_attribute_*() when accessing attributes. */
71 struct dict *_attr_dict;
72
73 /* Module-specific contexts. See mail_storage_module_id. */
74 ARRAY(union mail_user_module_context *) module_contexts;
75
76 /* User doesn't exist (as reported by userdb lookup when looking
77 up home) */
78 bool nonexistent:1;
79 /* Either home is set or there is no home for the user. */
80 bool home_looked_up:1;
81 /* User is anonymous */
82 bool anonymous:1;
83 /* This is an autocreated user (e.g. for shared namespace or
84 lda raw storage) */
85 bool autocreated:1;
86 /* mail_user_init() has been called */
87 bool initialized:1;
88 /* The initial namespaces have been created and
89 hook_mail_namespaces_created() has been called. */
90 bool namespaces_created:1;
91 /* SET_STR_VARS in user's all settings have been expanded.
92 This happens near the beginning of the user initialization,
93 so this is rarely needed to be checked. */
94 bool settings_expanded:1;
95 /* Shortcut to mail_storage_settings.mail_debug */
96 bool mail_debug:1;
97 /* If INBOX can't be opened, log an error, but only once. */
98 bool inbox_open_error_logged:1;
99 /* Fuzzy search works for this user (FTS enabled) */
100 bool fuzzy_search:1;
101 /* We're running dsync */
102 bool dsyncing:1;
103 /* Failed to create attribute dict, don't try again */
104 bool attr_dict_failed:1;
105 /* We're deinitializing the user */
106 bool deinitializing:1;
107 /* Enable administrator user commands for the user */
108 bool admin:1;
109 /* Enable all statistics gathering */
110 bool stats_enabled:1;
111 /* This session was restored (e.g. IMAP unhibernation) */
112 bool session_restored:1;
113 };
114
115 struct mail_user_module_register {
116 unsigned int id;
117 };
118
119 union mail_user_module_context {
120 struct mail_user_vfuncs super;
121 struct mail_user_module_register *reg;
122 };
123 extern struct mail_user_module_register mail_user_module_register;
124 extern struct auth_master_connection *mail_user_auth_master_conn;
125 extern const struct var_expand_func_table *mail_user_var_expand_func_table;
126
127 struct mail_user *mail_user_alloc(struct event *parent_event,
128 const char *username,
129 const struct setting_parser_info *set_info,
130 const struct mail_user_settings *set);
131 struct mail_user *
132 mail_user_alloc_nodup_set(struct event *parent_event,
133 const char *username,
134 const struct setting_parser_info *set_info,
135 const struct mail_user_settings *set);
136 /* Returns -1 if settings were invalid. */
137 int mail_user_init(struct mail_user *user, const char **error_r);
138
139 void mail_user_ref(struct mail_user *user);
140 void mail_user_unref(struct mail_user **user);
141 /* Assert that this is the last reference for the user and unref it. */
142 void mail_user_deinit(struct mail_user **user);
143
144 /* Duplicate a mail_user. mail_user_init() and mail_namespaces_init() need to
145 be called before the user is usable. */
146 struct mail_user *mail_user_dup(struct mail_user *user);
147
148 /* Find another user from the given user's namespaces. */
149 struct mail_user *mail_user_find(struct mail_user *user, const char *name);
150
151 /* Specify mail location %variable expansion data. */
152 void mail_user_set_vars(struct mail_user *user, const char *service,
153 const struct mail_user_connection_data *conn);
154 /* Return %variable expansion table for the user. */
155 const struct var_expand_table *
156 mail_user_var_expand_table(struct mail_user *user);
157
158 /* Specify the user's home directory. This should be called also when it's
159 known that the user doesn't have a home directory to avoid the internal
160 lookup. */
161 void mail_user_set_home(struct mail_user *user, const char *home);
162 /* Get the home directory for the user. Returns 1 if home directory looked up
163 successfully, 0 if there is no home directory (either user doesn't exist or
164 has no home directory) or -1 if lookup failed. The returned home string
165 is valid until the user is freed. */
166 int mail_user_get_home(struct mail_user *user, const char **home_r);
167 /* Appends path + file prefix for creating a temporary file.
168 The file prefix doesn't contain any uniqueness. */
169 void mail_user_set_get_temp_prefix(string_t *dest,
170 const struct mail_user_settings *set);
171 /* Get volatile directory from INBOX namespace if configured. Returns NULL if
172 none is configured. */
173 const char *mail_user_get_volatile_dir(struct mail_user *user);
174 /* Returns 1 on success, 0 if lock_secs is reached, -1 on error */
175 int mail_user_lock_file_create(struct mail_user *user, const char *lock_fname,
176 unsigned int lock_secs,
177 struct file_lock **lock_r, const char **error_r);
178
179 /* Returns TRUE if plugin is loaded for the user. */
180 bool mail_user_is_plugin_loaded(struct mail_user *user, struct module *module);
181 /* If name exists in plugin_envs, return its value. */
182 const char *mail_user_plugin_getenv(struct mail_user *user, const char *name);
183 bool mail_user_plugin_getenv_bool(struct mail_user *user, const char *name);
184 const char *mail_user_set_plugin_getenv(const struct mail_user_settings *set,
185 const char *name);
186 bool mail_user_set_plugin_getenv_bool(const struct mail_user_settings *set,
187 const char *name);
188
189 /* Add more namespaces to user's namespaces. The ->next pointers may be
190 changed, so the namespaces pointer will be updated to user->namespaces. */
191 void mail_user_add_namespace(struct mail_user *user,
192 struct mail_namespace **namespaces);
193 /* Drop autocreated shared namespaces that don't have any "usable" mailboxes. */
194 void mail_user_drop_useless_namespaces(struct mail_user *user);
195
196 /* Replace ~/ at the beginning of the path with the user's home directory. */
197 const char *mail_user_home_expand(struct mail_user *user, const char *path);
198 /* Returns 0 if ok, -1 if home directory isn't set. */
199 int mail_user_try_home_expand(struct mail_user *user, const char **path);
200 /* Returns unique user+ip identifier for anvil. */
201 const char *mail_user_get_anvil_userip_ident(struct mail_user *user);
202
203 /* Basically the same as mail_storage_find_class(), except automatically load
204 storage plugins when needed. */
205 struct mail_storage *
206 mail_user_get_storage_class(struct mail_user *user, const char *name);
207
208 /* Initialize SSL client settings from mail_user settings. */
209 void mail_user_init_ssl_client_settings(struct mail_user *user,
210 struct ssl_iostream_settings *ssl_set_r);
211
212 /* Initialize fs_settings from mail_user settings. */
213 void mail_user_init_fs_settings(struct mail_user *user,
214 struct fs_settings *fs_set,
215 struct ssl_iostream_settings *ssl_set_r);
216
217 /* Fill statistics for user. By default there are no statistics, so stats
218 plugin must be loaded to have anything filled. */
219 void mail_user_stats_fill(struct mail_user *user, struct stats *stats);
220
221 /* Try to mkdir() user's home directory. Ideally this should be called only
222 after the caller tries to create a file to the home directory, but it fails
223 with ENOENT. This way it avoids unnecessary disk IO to the home. */
224 int mail_user_home_mkdir(struct mail_user *user);
225
226 /* Return dict_op_settings for the user. The returned settings are valid until
227 the user is freed. */
228 const struct dict_op_settings *
229 mail_user_get_dict_op_settings(struct mail_user *user);
230
231
232 /* Obtain the postmaster address to be used for this user as an RFC 5322 (IMF)
233 address. Returns false if the configured postmaster address is invalid in
234 which case error_r contains the error message. */
235 static inline bool
mail_user_get_postmaster_address(struct mail_user * user,const struct message_address ** address_r,const char ** error_r)236 mail_user_get_postmaster_address(struct mail_user *user,
237 const struct message_address **address_r,
238 const char **error_r)
239 {
240 return mail_user_set_get_postmaster_address(user->set, address_r,
241 error_r);
242 }
243
244 /* Obtain the postmaster address to be used for this user as an RFC 5321 (SMTP)
245 address. Returns false if the configured postmaster address is invalid in
246 which case error_r contains the error message. */
247 static inline bool
mail_user_get_postmaster_smtp(struct mail_user * user,const struct smtp_address ** address_r,const char ** error_r)248 mail_user_get_postmaster_smtp(struct mail_user *user,
249 const struct smtp_address **address_r,
250 const char **error_r)
251 {
252 return mail_user_set_get_postmaster_smtp(user->set, address_r,
253 error_r);
254 }
255
256 #endif
257