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