bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "lib.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "ostream.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "connection.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "restrict-access.h"
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi#include "settings-parser.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "master-service.h"
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen#include "master-service-settings.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-namespace.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage-settings.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "mail-storage-service.h"
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch#include "smtp-address.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "quota-private.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen#include "quota-plugin.h"
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi#include "quota-status-settings.h"
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenenum quota_protocol {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen QUOTA_PROTOCOL_UNKNOWN = 0,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen QUOTA_PROTOCOL_POSTFIX
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstruct quota_client {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct connection conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch struct smtp_address *recipient;
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen uoff_t size;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomistatic struct quota_status_settings *quota_status_settings;
9f0429766dcacea2544594a6efc3c0c3fa022e6aAki Tuomistatic pool_t quota_status_pool;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic enum quota_protocol protocol;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct mail_storage_service_ctx *storage_service;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct connection_list *clients;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainenstatic char *nouser_reply;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client = i_new(struct quota_client, 1);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_init_server(clients, &client->conn,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen "(quota client)", conn->fd, conn->fd);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_accept(conn);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_reset(struct quota_client *client)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_free_and_null(client->recipient);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvistatic enum quota_alloc_result
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärviquota_check(struct mail_user *user, uoff_t mail_size, const char **error_r)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(user);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_namespace *ns;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mailbox *box;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_transaction_context *ctx;
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi enum quota_alloc_result ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (quser == NULL) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen /* no quota for user */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi return QUOTA_ALLOC_RESULT_OK;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ns = mail_namespace_find_inbox(user->namespaces);
e66cd209fcab4817d2234d0121b404925dc60034Timo Sirainen box = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_POST_SESSION);
61cf001f1944d92eb25f113ba4c08985d6e30d53Timo Sirainen mailbox_set_reason(box, "quota status");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ctx = quota_transaction_begin(box);
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi const char *internal_error;
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi ret = quota_test_alloc(ctx, I_MAX(1, mail_size), &internal_error);
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi if (ret == QUOTA_ALLOC_RESULT_TEMPFAIL)
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi i_error("quota check failed: %s", internal_error);
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi *error_r = quota_alloc_result_errstr(ret, ctx);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen quota_transaction_rollback(&ctx);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mailbox_free(&box);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_handle_request(struct quota_client *client)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_storage_service_input input;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_storage_service_user *service_user;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_user *user;
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen const char *value = NULL, *error;
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi const char *detail ATTR_UNUSED;
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi char delim ATTR_UNUSED;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen int ret;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (client->recipient == NULL) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, "action=DUNNO\n\n");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&input);
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch smtp_address_detail_parse_temp(quota_status_settings->recipient_delimiter,
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch client->recipient, &input.username, &delim,
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch &detail);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ret = mail_storage_service_lookup_next(storage_service, &input,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen &service_user, &user, &error);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen restrict_access_allow_coredumps(TRUE);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (ret == 0) {
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen value = nouser_reply;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen } else if (ret > 0) {
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi enum quota_alloc_result qret = quota_check(user, client->size,
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi &error);
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi switch (qret) {
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OK: /* under quota */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi value = mail_user_plugin_getenv(user,
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_success");
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen if (value == NULL)
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen value = "OK";
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi break;
7f4fa37676bac8efcf4e2ac706172b1bad779a8aMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OVER_MAXSIZE:
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi /* even over maximum quota */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT:
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi value = mail_user_plugin_getenv(user,
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_toolarge");
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi /* fall through */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OVER_QUOTA:
d28a4f3578da61ac734981d87d7077dd4747417dTimo Sirainen if (value == NULL)
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi value = mail_user_plugin_getenv(user,
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_overquota");
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen if (value == NULL)
cf0184bf140bec4262fb0434bbdc10cf2c3efc1aTimo Sirainen value = t_strdup_printf("554 5.2.2 %s", error);
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi break;
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_TEMPFAIL:
b14f93ea4f7e9b78e5adbabcc78bd2f63d2bcd36Martti Rannanjärvi case QUOTA_ALLOC_RESULT_BACKGROUND_CALC:
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi ret = -1;
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi break;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
b8164b588348c124acc469841ec7a5ca93a8efcdTimo Sirainen value = t_strdup(value); /* user's pool is being freed */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_user_unref(&user);
eb318ea05532d2e54ed3bfc89bc15dcf1adae838Timo Sirainen mail_storage_service_user_unref(&service_user);
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen } else {
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen i_error("Failed to lookup user %s: %s", input.username, error);
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen error = "Temporary internal error";
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (ret < 0) {
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen /* temporary failure */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, t_strdup_printf(
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen "action=DEFER_IF_PERMIT %s\n\n", error));
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen } else {
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen o_stream_send_str(client->conn.output,
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen t_strdup_printf("action=%s\n\n", value));
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic int client_input_line(struct connection *conn, const char *line)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch const char *error;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (*line == '\0') {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_cork(conn->output);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_handle_request(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_uncork(conn->output);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_reset(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 1;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (client->recipient == NULL &&
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch strncmp(line, "recipient=", 10) == 0) {
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch if (smtp_address_parse_path(default_pool, line + 10,
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch SMTP_ADDRESS_PARSE_FLAG_ALLOW_LOCALPART |
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL,
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch &client->recipient, &error) < 0) {
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch i_error("quota-status: "
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch "Client sent invalid recipient address: %s",
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch error);
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch return 0;
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch }
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch } else if (strncmp(line, "size=", 5) == 0) {
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen if (str_to_uoff(line+5, &client->size) < 0)
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen client->size = 0;
f8b73b7a49b4471bdb92daa9284f181322709011Timo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 1;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_destroy(struct connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_deinit(&client->conn);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen client_reset(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_free(client);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_destroyed(master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct connection_settings client_set = {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .input_max_size = (size_t)-1,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .output_max_size = (size_t)-1,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .client = FALSE
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic const struct connection_vfuncs client_vfuncs = {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .destroy = client_destroy,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen .input_line = client_input_line
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen};
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_preinit(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
816d20be0cf95fc4eb1a8aa716639e73b8ba525eMartti Rannanjärvi restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen restrict_access_allow_coredumps(TRUE);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_init(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi static const struct setting_parser_info *set_roots[] = {
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi &quota_status_setting_parser_info,
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi NULL
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi };
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen struct mail_storage_service_input input;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct setting_parser_info *user_info;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct setting_parser_context *set_parser;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct mail_user_settings *user_set;
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi const struct quota_status_settings *set;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const char *value, *error;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool_t pool;
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen clients = connection_list_init(&client_set, &client_vfuncs);
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi storage_service = mail_storage_service_init(master_service, set_roots,
e0dae5d76ea0a4aef849602750ce73dfae995bc8Martti Rannanjärvi MAIL_STORAGE_SERVICE_FLAG_ALLOW_ROOT |
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_USERDB_LOOKUP |
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_TEMP_PRIV_DROP |
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen MAIL_STORAGE_SERVICE_FLAG_ENABLE_CORE_DUMPS |
7f5c66ef0fbdca9dc1657490099bdb87922099a4Timo Sirainen MAIL_STORAGE_SERVICE_FLAG_NO_CHDIR);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
efe78d3ba24fc866af1c79b9223dc0809ba26cadStephan Bosch i_zero(&input);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.service = "quota-status";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.module = "mail";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen input.username = "";
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen
9f0429766dcacea2544594a6efc3c0c3fa022e6aAki Tuomi quota_status_pool = pool_alloconly_create("quota status settings", 512);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool = pool_alloconly_create("service all settings", 4096);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen if (mail_storage_service_read_settings(storage_service, &input, pool,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen &user_info, &set_parser,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen &error) < 0)
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen i_fatal("%s", error);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen user_set = master_service_settings_parser_get_others(master_service,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen set_parser)[0];
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi set = master_service_settings_get_others(master_service)[1];
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi quota_status_settings = settings_dup(&quota_status_setting_parser_info, set,
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi quota_status_pool);
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen value = mail_user_set_plugin_getenv(user_set, "quota_status_nouser");
9f0429766dcacea2544594a6efc3c0c3fa022e6aAki Tuomi nouser_reply = p_strdup(quota_status_pool,
9f0429766dcacea2544594a6efc3c0c3fa022e6aAki Tuomi value != NULL ? value : "REJECT Unknown user");
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen pool_unref(&pool);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void main_deinit(void)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
9f0429766dcacea2544594a6efc3c0c3fa022e6aAki Tuomi pool_unref(&quota_status_pool);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_list_deinit(&clients);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_storage_service_deinit(&storage_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenint main(int argc, char *argv[])
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen{
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen enum master_service_flags service_flags =
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen MASTER_SERVICE_FLAG_KEEP_CONFIG_OPEN;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen int c;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen protocol = QUOTA_PROTOCOL_UNKNOWN;
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen master_service = master_service_init("quota-status", service_flags,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen &argc, &argv, "p:");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen switch (c) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen case 'p':
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (strcmp(optarg, "postfix") == 0)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen protocol = QUOTA_PROTOCOL_POSTFIX;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen else
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_fatal("Unknown -p parameter: '%s'", optarg);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen break;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen default:
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return FATAL_DEFAULT;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen }
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen if (protocol == QUOTA_PROTOCOL_UNKNOWN)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_fatal("Missing -p parameter");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c8fff8f35c459f8577694b585183228ba1631fe2Timo Sirainen master_service_init_log(master_service, "quota-status: ");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_preinit();
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_init();
d6b3cfd855c0eebed68be50d3111de1b5a6afeb0Timo Sirainen master_service_init_finish(master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_run(master_service, client_connected);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen main_deinit();
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_deinit(&master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen return 0;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen}