#include "imap-id.h"
#include "imap-resp-code.h"
#include "master-service.h"
+#include "master-service-settings.h"
#include "master-service-ssl-settings.h"
#include "login-client.h"
#include "imap-login-client.h"
return &imap_client->common;
}
-static int imap_client_create(struct client *client, void **other_sets)
+static int imap_client_create(struct client *client)
{
struct imap_client *imap_client = (struct imap_client *)client;
+ const char *error;
+
+ if (master_service_settings_get(client->event,
+ &imap_login_setting_parser_info, 0,
+ &imap_client->set, &error) < 0) {
+ e_error(client->event, "%s", error);
+ return -1;
+ }
- imap_client->set = other_sets[0];
imap_client->parser =
imap_parser_create(imap_client->common.input,
imap_client->common.output,
cmd_id_free(imap_client);
}
+ master_service_settings_free(imap_client->set);
i_free_and_null(imap_client->proxy_backend_capability);
imap_parser_unref(&imap_client->parser);
}
NULL
};
-static const struct setting_parser_info imap_login_setting_parser_info = {
+const struct setting_parser_info imap_login_setting_parser_info = {
.module_name = "imap-login",
.defines = imap_login_setting_defines,
.defaults = &imap_login_default_settings,
.struct_size = sizeof(struct imap_login_settings),
+ .pool_offset1 = 1 + offsetof(struct imap_login_settings, pool),
.dependencies = imap_login_setting_dependencies
};
#define IMAP_LOGIN_SETTINGS_H
struct imap_login_settings {
+ pool_t pool;
const char *imap_capability;
const char *imap_id_send;
bool imap_literal_minus;
};
extern const struct setting_parser_info *imap_login_setting_roots[];
+extern const struct setting_parser_info imap_login_setting_parser_info;
#endif
struct imap_urlauth_client {
struct client common;
- const struct imap_urlauth_login_settings *set;
-
bool version_received:1;
};
return &uauth_client->common;
}
-static int imap_urlauth_client_create
-(struct client *client, void **other_sets)
+static int imap_urlauth_client_create(struct client *client)
{
- struct imap_urlauth_client *uauth_client =
- (struct imap_urlauth_client *)client;
-
- uauth_client->set = other_sets[0];
client->io = io_add_istream(client->input, client_input, client);
return 0;
}
#include "var-expand.h"
#include "master-interface.h"
#include "master-service.h"
+#include "master-service-settings.h"
#include "master-service-ssl-settings.h"
#include "login-client.h"
#include "anvil-client.h"
CLIENT_AUTH_FAIL_CODE_COUNT);
static const char *client_get_log_str(struct client *client, const char *msg);
+static const struct var_expand_table *
+get_var_expand_table(struct client *client);
void login_client_hooks_add(struct module *module,
const struct login_client_hooks *hooks)
return FALSE;
}
-struct client *
-client_alloc(int fd, pool_t pool,
- const struct master_service_connection *conn,
- const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set,
- const struct master_service_ssl_server_settings *ssl_server_set)
+static void
+client_var_expand_callback(struct event *event,
+ const struct var_expand_table **tab_r,
+ const struct var_expand_func_table **func_tab_r ATTR_UNUSED)
+{
+ struct client *client = event_get_ptr(event, "client");
+
+ *tab_r = get_var_expand_table(client);
+}
+
+static int client_settings_read(struct client *client, const char **error_r)
+{
+ i_assert(client->set == NULL);
+
+ if (login_settings_read(&client->local_ip, &client->ip,
+ client->local_name, error_r) < 0 ||
+ master_service_settings_get(client->event,
+ &login_setting_parser_info,
+ 0, &client->set, error_r) < 0 ||
+ master_service_settings_get(client->event,
+ &master_service_ssl_setting_parser_info,
+ 0, &client->ssl_set, error_r) < 0 ||
+ master_service_settings_get(client->event,
+ &master_service_ssl_server_setting_parser_info,
+ 0, &client->ssl_server_set, error_r) < 0) {
+ master_service_settings_free(client->set);
+ master_service_settings_free(client->ssl_set);
+ return -1;
+ }
+ return 0;
+}
+
+int client_alloc(int fd, const struct master_service_connection *conn,
+ struct client **client_r)
{
struct client *client;
+ const char *error;
i_assert(fd != -1);
+ pool_t pool = pool_alloconly_create("login client", 8*1024);
client = login_binary->client_vfuncs->alloc(pool);
client->v = *login_binary->client_vfuncs;
if (client->v.auth_send_challenge == NULL)
client->pool = pool;
client->preproxy_pool = pool_alloconly_create(MEMPOOL_GROWING"preproxy pool", 256);
- client->set = set;
- client->ssl_set = ssl_set;
- client->ssl_server_set = ssl_server_set;
p_array_init(&client->module_contexts, client->pool, 5);
client->fd = fd;
event_add_ip(client->event, "remote_ip", &conn->remote_ip);
event_add_int(client->event, "remote_port", conn->remote_port);
event_add_str(client->event, "service", login_binary->protocol);
+
+ /* Get settings before using log callback */
+ event_set_ptr(client->event, MASTER_SERVICE_VAR_EXPAND_CALLBACK,
+ client_var_expand_callback);
+ event_set_ptr(client->event, "client", client);
+ if (client_settings_read(client, &error) < 0) {
+ e_error(client->event, "%s", error);
+ event_unref(&client->event);
+ pool_unref(&client->pool);
+ return -1;
+ }
+
event_set_log_message_callback(client->event, client_log_msg_callback,
client);
client->connection_trusted = client_is_trusted(client);
client_open_streams(client);
- return client;
+ *client_r = client;
+ return 0;
}
-int client_init(struct client *client, void **other_sets)
+int client_init(struct client *client)
{
if (last_client == NULL)
last_client = client;
client_idle_disconnect_timeout, client);
hook_login_client_allocated(client);
- if (client->v.create(client, other_sets) < 0)
+ if (client->v.create(client) < 0)
return -1;
client->create_finished = TRUE;
client->refcount++;
}
+static void client_settings_free(struct client *client)
+{
+ master_service_settings_free(client->set);
+ master_service_settings_free(client->ssl_set);
+ master_service_settings_free(client->ssl_server_set);
+}
+
bool client_unref(struct client **_client)
{
struct client *client = *_client;
return TRUE;
if (!client->create_finished) {
+ client_settings_free(client);
i_stream_unref(&client->input);
o_stream_unref(&client->output);
pool_unref(&client->preproxy_pool);
i_close_fd(&client->fd);
event_unref(&client->event);
event_unref(&client->event_auth);
+ client_settings_free(client);
i_free(client->proxy_user);
i_free(client->proxy_master_user);
struct client *client = context;
struct ssl_iostream_context *ssl_ctx;
struct ssl_iostream_settings ssl_set;
- void **other_sets;
const char *error;
if (client->ssl_servername_settings_read)
return 0;
client->ssl_servername_settings_read = TRUE;
+ const struct login_settings *old_set = client->set;
+ const struct master_service_ssl_settings *old_ssl_set = client->ssl_set;
+ const struct master_service_ssl_server_settings *old_ssl_server_set =
+ client->ssl_server_set;
+ client->set = NULL;
+ client->ssl_set = NULL;
+ client->ssl_server_set = NULL;
+
client->local_name = p_strdup(client->pool, name);
- client->set = login_settings_read(client->pool, &client->local_ip,
- &client->ip, name,
- &client->ssl_set,
- &client->ssl_server_set, &other_sets);
+ if (client_settings_read(client, error_r) < 0) {
+ client->set = old_set;
+ client->ssl_set = old_ssl_set;
+ client->ssl_server_set = old_ssl_server_set;
+ return -1;
+ }
+ master_service_settings_free(old_set);
+ master_service_settings_free(old_ssl_set);
+ master_service_settings_free(old_ssl_server_set);
master_service_ssl_server_settings_to_iostream_set(client->ssl_set,
client->ssl_server_set, pool_datastack_create(), &ssl_set);
struct client_vfuncs {
struct client *(*alloc)(pool_t pool);
- int (*create)(struct client *client, void **other_sets);
+ int (*create)(struct client *client);
void (*destroy)(struct client *client);
void (*notify_auth_ready)(struct client *client);
void (*notify_disconnect)(struct client *client,
const struct login_client_hooks *hooks);
void login_client_hooks_remove(const struct login_client_hooks *hooks);
-struct client *
-client_alloc(int fd, pool_t pool,
- const struct master_service_connection *conn,
- const struct login_settings *set,
- const struct master_service_ssl_settings *ssl_set,
- const struct master_service_ssl_server_settings *ssl_server_set);
-int client_init(struct client *client, void **other_sets);
+int client_alloc(int fd, const struct master_service_connection *conn,
+ struct client **client_r);
+int client_init(struct client *client);
void client_disconnect(struct client *client, const char *reason,
bool add_disconnected_prefix);
void client_destroy(struct client *client, const char *reason);
extern const struct login_settings *global_login_settings;
extern const struct master_service_ssl_settings *global_ssl_settings;
-extern void **global_other_settings;
extern const struct ip_addr *login_source_ips;
extern unsigned int login_source_ips_idx, login_source_ips_count;
.defaults = &login_default_settings,
.struct_size = sizeof(struct login_settings),
+ .pool_offset1 = 1 + offsetof(struct login_settings, pool),
.check_func = login_settings_check
};
}
/* </settings checks> */
-static const struct var_expand_table *
-login_set_var_expand_table(const struct master_service_settings_input *input)
-{
- const struct var_expand_table stack_tab[] = {
- { 'l', net_ip2addr(&input->local_ip), "lip" },
- { 'r', net_ip2addr(&input->remote_ip), "rip" },
- { 'p', my_pid, "pid" },
- { 's', input->service, "service" },
- { '\0', input->local_name, "local_name" },
- /* aliases */
- { '\0', net_ip2addr(&input->local_ip), "local_ip" },
- { '\0', net_ip2addr(&input->remote_ip), "remote_ip" },
- /* NOTE: Make sure login_log_format_elements_split has all these
- variables (in client-common.c:get_var_expand_table()). */
- { '\0', NULL, NULL }
- };
- struct var_expand_table *tab;
-
- tab = t_malloc_no0(sizeof(stack_tab));
- memcpy(tab, stack_tab, sizeof(stack_tab));
- return tab;
-}
-
-static void *
-login_setting_dup(pool_t pool, const struct setting_parser_info *info,
- const struct setting_parser_context *parser)
-{
- const char *error;
- void *src_set, *dest;
-
- src_set = settings_parser_get_root_set(parser, info);
- dest = settings_dup(info, src_set, pool);
- if (!settings_check(info, pool, dest, &error)) {
- const char *name = info->module_name;
-
- i_fatal("settings_check(%s) failed: %s",
- name != NULL ? name : "unknown", error);
- }
- return dest;
-}
-
-static struct login_settings *
-login_settings_read_real(
- pool_t pool, const struct ip_addr *local_ip,
- const struct ip_addr *remote_ip, const char *local_name,
- const struct master_service_ssl_settings **ssl_set_r,
- const struct master_service_ssl_server_settings **ssl_server_set_r,
- void ***other_settings_r)
+int login_settings_read(const struct ip_addr *local_ip,
+ const struct ip_addr *remote_ip,
+ const char *local_name, const char **error_r)
{
struct master_service_settings_input input;
struct master_service_settings_output output;
- const char *error;
- struct setting_parser_context *parser;
- void **sets;
- unsigned int i, count;
i_zero(&input);
input.roots = login_set_roots;
input.service = login_binary->protocol;
input.local_name = local_name;
+ input.disable_check_settings = TRUE;
if (local_ip != NULL)
input.local_ip = *local_ip;
if (remote_ip != NULL)
input.remote_ip = *remote_ip;
- if (master_service_settings_read(master_service, &input,
- &output, &error) < 0)
- i_fatal("%s", error);
- parser = master_service_get_settings_parser(master_service);
-
- for (count = 0; input.roots[count] != NULL; count++) ;
- sets = p_new(pool, void *, count + 1);
- for (i = 0; i < count; i++)
- sets[i] = login_setting_dup(pool, input.roots[i], parser);
-
- if (settings_var_expand(&login_setting_parser_info, sets[0], pool,
- login_set_var_expand_table(&input), &error) <= 0)
- i_fatal("Failed to expand settings: %s", error);
-
- *ssl_set_r =
- login_setting_dup(pool, &master_service_ssl_setting_parser_info,
- parser);
- *ssl_server_set_r =
- login_setting_dup(pool, &master_service_ssl_server_setting_parser_info,
- parser);
- *other_settings_r = sets + 1;
- return sets[0];
-}
-
-struct login_settings *
-login_settings_read(
- pool_t pool, const struct ip_addr *local_ip,
- const struct ip_addr *remote_ip, const char *local_name,
- const struct master_service_ssl_settings **ssl_set_r,
- const struct master_service_ssl_server_settings **ssl_server_set_r,
- void ***other_settings_r)
-{
- struct login_settings *login_set;
-
- T_BEGIN {
- login_set = login_settings_read_real(pool, local_ip, remote_ip,
- local_name, ssl_set_r,
- ssl_server_set_r,
- other_settings_r);
- } T_END;
-
- return login_set;
+ return master_service_settings_read(master_service, &input,
+ &output, error_r);
}
struct master_service_ssl_server_settings;
struct login_settings {
+ pool_t pool;
const char *login_trusted_networks;
const char *login_source_ips;
const char *login_greeting;
extern const struct setting_parser_info **login_set_roots;
extern const struct setting_parser_info login_setting_parser_info;
-struct login_settings *
-login_settings_read(pool_t pool,
- const struct ip_addr *local_ip,
- const struct ip_addr *remote_ip,
- const char *local_name,
- const struct master_service_ssl_settings **ssl_set_r,
- const struct master_service_ssl_server_settings **ssl_server_set_r,
- void ***other_settings_r) ATTR_NULL(2, 3, 4);
+int login_settings_read(const struct ip_addr *local_ip,
+ const struct ip_addr *remote_ip,
+ const char *local_name, const char **error_r)
+ ATTR_NULL(1, 2, 3);
#endif
#include "anvil-client.h"
#include "auth-client.h"
#include "dsasl-client.h"
+#include "master-service-settings.h"
#include "master-service-ssl-settings.h"
#include "login-proxy.h"
client_connected(struct master_service_connection *conn)
{
struct client *client;
- const struct login_settings *set;
- const struct master_service_ssl_settings *ssl_set;
- const struct master_service_ssl_server_settings *ssl_server_set;
- pool_t pool;
- void **other_sets;
master_service_client_connection_accept(conn);
/* make sure we're connected (or attempting to connect) to auth */
auth_client_connect(auth_client);
- pool = pool_alloconly_create("login client", 8*1024);
- set = login_settings_read(pool, &conn->local_ip,
- &conn->remote_ip, NULL,
- &ssl_set, &ssl_server_set, &other_sets);
-
- client = client_alloc(conn->fd, pool, conn, set,
- ssl_set, ssl_server_set);
+ if (client_alloc(conn->fd, conn, &client) < 0) {
+ net_disconnect(conn->fd);
+ master_service_client_connection_destroyed(master_service);
+ return;
+ }
if (ssl_connections || conn->ssl) {
if (client_init_ssl(client) < 0) {
client_unref(&client);
return;
}
}
- if (client_init(client, other_sets) < 0) {
+ if (client_init(client) < 0) {
client_destroy(client, "Failed to initialize client");
return;
}
client->event_auth = event_create(client->event);
event_add_category(client->event_auth, &event_category_auth);
- event_set_min_log_level(client->event_auth, set->auth_verbose ?
+ event_set_min_log_level(client->event_auth, client->set->auth_verbose ?
LOG_TYPE_INFO : LOG_TYPE_WARNING);
timeout_remove(&auth_client_to);
timeout_remove(&auth_client_to);
client_common_deinit();
dsasl_clients_deinit();
+
+ master_service_settings_free(global_login_settings);
+ master_service_settings_free(global_ssl_settings);
+ master_service_settings_free(global_ssl_server_settings);
}
int login_binary_run(struct login_binary *binary,
MASTER_SERVICE_FLAG_TRACK_LOGIN_STATE |
MASTER_SERVICE_FLAG_HAVE_STARTTLS |
MASTER_SERVICE_FLAG_NO_SSL_INIT;
- pool_t set_pool;
- const char *login_socket;
+ const char *login_socket, *error;
int c;
login_binary = binary;
login_binary->preinit();
- set_pool = pool_alloconly_create("global login settings", 4096);
- global_login_settings =
- login_settings_read(set_pool, NULL, NULL, NULL,
- &global_ssl_settings,
- &global_ssl_server_settings,
- &global_other_settings);
+ if (login_settings_read(NULL, NULL, NULL, &error) < 0 ||
+ master_service_settings_get(NULL, &login_setting_parser_info,
+ MASTER_SERVICE_SETTINGS_GET_FLAG_NO_EXPAND,
+ &global_login_settings, &error) < 0)
+ i_fatal("%s", error);
+ global_ssl_settings = master_service_settings_get_or_fatal(NULL,
+ &master_service_ssl_setting_parser_info);
+ global_ssl_server_settings = master_service_settings_get_or_fatal(NULL,
+ &master_service_ssl_server_setting_parser_info);
if (argv[optind] != NULL)
login_socket = argv[optind];
master_service_run(master_service, client_connected);
main_deinit();
array_free(&login_source_ips_array);
- pool_unref(&set_pool);
master_service_deinit(&master_service);
return 0;
}
return &pop3_client->common;
}
-static int pop3_client_create(struct client *client ATTR_UNUSED,
- void **other_sets ATTR_UNUSED)
+static int pop3_client_create(struct client *client ATTR_UNUSED)
{
return 0;
}
#include "str.h"
#include "strescape.h"
#include "master-service.h"
+#include "master-service-settings.h"
#include "master-service-ssl-settings.h"
#include "client.h"
#include "client-authenticate.h"
return &subm_client->common;
}
-static int submission_client_create(struct client *client,
- void **other_sets)
+static int submission_client_create(struct client *client)
{
static const char *const xclient_extensions[] =
{ "FORWARD", NULL };
struct submission_client *subm_client =
container_of(client, struct submission_client, common);
struct smtp_server_settings smtp_set;
+ const char *error;
+
+ if (master_service_settings_get(client->event,
+ &submission_login_setting_parser_info,
+ 0, &subm_client->set, &error) < 0) {
+ e_error(client->event, "%s", error);
+ return -1;
+ }
- subm_client->set = other_sets[0];
client_parse_backend_capabilities(subm_client);
i_zero(&smtp_set);
if (subm_client->conn != NULL)
smtp_server_connection_close(&subm_client->conn, NULL);
+ master_service_settings_free(subm_client->set);
i_free_and_null(subm_client->proxy_xclient);
}
.defaults = &submission_login_default_settings,
.struct_size = sizeof(struct submission_login_settings),
+ .pool_offset1 = 1 + offsetof(struct submission_login_settings, pool),
.check_func = submission_login_settings_check,
.dependencies = submission_login_setting_dependencies
};
/* </settings checks> */
struct submission_login_settings {
+ pool_t pool;
const char *hostname;
/* submission: */
};
extern const struct setting_parser_info *submission_login_setting_roots[];
+extern const struct setting_parser_info submission_login_setting_parser_info;
#endif