bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomistatic struct quota_status_settings *quota_status_settings;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct mail_storage_service_ctx *storage_service;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_connected(struct master_service_connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen connection_init_server(clients, &client->conn,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_accept(conn);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_reset(struct quota_client *client)
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärviquota_check(struct mail_user *user, uoff_t mail_size, const char **error_r)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(user);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen /* no quota for user */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ns = mail_namespace_find_inbox(user->namespaces);
e66cd209fcab4817d2234d0121b404925dc60034Timo Sirainen box = mailbox_alloc(ns->list, "INBOX", MAILBOX_FLAG_POST_SESSION);
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi ret = quota_test_alloc(ctx, I_MAX(1, mail_size), &internal_error);
b62139aae0a0099d0ede35b164b2870479f9b027Martti Rannanjärvi i_error("quota check failed: %s", internal_error);
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi *error_r = quota_alloc_result_errstr(ret, ctx);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_handle_request(struct quota_client *client)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct mail_storage_service_user *service_user;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, "action=DUNNO\n\n");
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch smtp_address_detail_parse_temp(quota_status_settings->recipient_delimiter,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen ret = mail_storage_service_lookup_next(storage_service, &input,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen } else if (ret > 0) {
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi enum quota_alloc_result qret = quota_check(user, client->size,
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OK: /* under quota */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_success");
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi /* even over maximum quota */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi case QUOTA_ALLOC_RESULT_OVER_QUOTA_LIMIT:
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_toolarge");
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi /* fall through */
38ce5769db11e7f52562610ee6e6fc4f0ea7888fMartti Rannanjärvi "quota_status_overquota");
cf0184bf140bec4262fb0434bbdc10cf2c3efc1aTimo Sirainen value = t_strdup_printf("554 5.2.2 %s", error);
b14f93ea4f7e9b78e5adbabcc78bd2f63d2bcd36Martti Rannanjärvi case QUOTA_ALLOC_RESULT_BACKGROUND_CALC:
b8164b588348c124acc469841ec7a5ca93a8efcdTimo Sirainen value = t_strdup(value); /* user's pool is being freed */
eb318ea05532d2e54ed3bfc89bc15dcf1adae838Timo Sirainen mail_storage_service_user_unref(&service_user);
f6008a666d9c3df66fd8a437369133e8519b4e24Timo Sirainen i_error("Failed to lookup user %s: %s", input.username, error);
dc03cb97c682a9d6b6e606008fd5ae884d01ff53Timo Sirainen /* temporary failure */
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen o_stream_send_str(client->conn.output, t_strdup_printf(
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic int client_input_line(struct connection *conn, const char *line)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch if (smtp_address_parse_path(default_pool, line + 10,
52f6112882fb2a4b7b921fc45640f4a9d748bae7Stephan Bosch "Client sent invalid recipient address: %s",
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic void client_destroy(struct connection *conn)
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen struct quota_client *client = (struct quota_client *)conn;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen master_service_client_connection_destroyed(master_service);
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic struct connection_settings client_set = {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainenstatic const struct connection_vfuncs client_vfuncs = {
816d20be0cf95fc4eb1a8aa716639e73b8ba525eMartti Rannanjärvi restrict_access_by_env(RESTRICT_ACCESS_FLAG_ALLOW_ROOT, NULL);
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi static const struct setting_parser_info *set_roots[] = {
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen const struct setting_parser_context *set_parser;
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen clients = connection_list_init(&client_set, &client_vfuncs);
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi storage_service = mail_storage_service_init(master_service, set_roots,
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_set = master_service_settings_parser_get_others(master_service,
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi set = master_service_settings_get_others(master_service)[1];
7dd64d2faf200cb8b87569cbc3206b54f95c9ff5Aki Tuomi quota_status_settings = settings_dup("a_status_setting_parser_info, set,
2a80aa687a48d3d3d00f8405fbff2b09fab4cbf3Timo Sirainen value = mail_user_set_plugin_getenv(user_set, "quota_status_nouser");
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen mail_storage_service_deinit(&storage_service);
c5acac1fd44571aabefc1b4db291488b87f822a0Timo Sirainen master_service = master_service_init("quota-status", service_flags,
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen while ((c = master_getopt(master_service)) > 0) {
c0699d9e0842a53c047fcbd695fa93ce435baa8fTimo Sirainen i_fatal("Unknown -p parameter: '%s'", optarg);
c8fff8f35c459f8577694b585183228ba1631fe2Timo Sirainen master_service_init_log(master_service, "quota-status: ");