imap-quota-plugin.c revision bffaca7da2825c2a77aa46022358e2f8400a0f94
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2005-2017 Dovecot authors, see the included COPYING file */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#include "imap-common.h"
46552a931924c2d743f045e95b08c3ce6beda91aTimo Sirainen#include "str.h"
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen#include "ostream.h"
c5f932968281763df360b9c97cef60f5f80d5e3dTimo Sirainen#include "imap-quote.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "mail-namespace.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "imap-commands.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "quota.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen#include "quota-plugin.h"
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen#include "imap-quota-plugin.h"
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
de754cb78f75e8b3b994cddafe41c9ed1467c33dTimo Sirainen#define QUOTA_USER_SEPARATOR ':'
f29756821a4c6b12b73e4a2a3e1c230117a43773Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char *imap_quota_plugin_version = DOVECOT_ABI_VERSION;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainenstatic struct module *imap_quota_module;
f0d93763f210ecdb85a115fdd0210a16cfc5ff5cTimo Sirainenstatic imap_client_created_func_t *next_hook_client_created;
53dfcefa9440a49d703e49193819a79be99c9ba6Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic const char *
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenimap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct quota_root *root)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *name;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch name = quota_root_get_name(root);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (user == owner || owner == NULL)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch return name;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch return t_strdup_printf("%s%c%s", owner->username,
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch QUOTA_USER_SEPARATOR, name);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch}
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschstatic int
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Boschquota_reply_write(string_t *str, struct mail_user *user,
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch struct mail_user *owner, struct quota_root *root)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch{
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch const char *name, *const *list;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch unsigned int i;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch uint64_t value, limit;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch size_t prefix_len, orig_len = str_len(str);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch int ret = 0;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch str_append(str, "* QUOTA ");
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch name = imap_quota_root_get_name(user, owner, root);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch imap_append_astring(str, name);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch str_append(str, " (");
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch prefix_len = str_len(str);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch list = quota_root_get_resources(root);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch for (i = 0; *list != NULL; list++) {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch ret = quota_get_resource(root, "", *list, &value, &limit);
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (ret < 0)
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch break;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (ret > 0) {
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (i > 0)
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen str_append_c(str, ' ');
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_printfa(str, "%s %llu %llu", *list,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen (unsigned long long)value,
2e78f05b11df23ec2731afaf8f19d5b5240cb29fTimo Sirainen (unsigned long long)limit);
2e78f05b11df23ec2731afaf8f19d5b5240cb29fTimo Sirainen i++;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
d1e7425048c61d71f41f737ba947687198842dc2Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (str_len(str) == prefix_len) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* this quota root doesn't have any quota actually enabled. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_truncate(str, orig_len);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen } else {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_append(str, ")\r\n");
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen }
660b99a7059824676b2b8d6f79b8e15d47df25a2Timo Sirainen return ret < 0 ? -1 : 0;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic bool cmd_getquotaroot(struct client_command_context *cmd)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct client *client = cmd->client;
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen struct quota_user *quser = QUOTA_USER_CONTEXT(client->user);
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct mail_namespace *ns;
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen struct mailbox *box;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct quota_root_iter *iter;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen struct quota_root *root;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *mailbox, *orig_mailbox, *name;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen string_t *quotaroot_reply, *quota_reply;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen int ret;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* <mailbox> */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (!client_read_string_args(cmd, 1, &mailbox))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return FALSE;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen orig_mailbox = mailbox;
9f627b360ed38fdc54cb02ec5e67246c3f0d5b0fTimo Sirainen
b9c76fe9d9ca194816606342da1ddbd9be6bc8abTimo Sirainen ns = client_find_namespace(cmd, &mailbox);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (ns == NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (quser == NULL) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_tagline(cmd, "OK No quota.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen return TRUE;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen }
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (ns->owner != NULL && ns->owner != client->user) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_tagline(cmd, "NO Not showing other users' quota.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen return TRUE;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen }
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen box = mailbox_alloc(ns->list, mailbox, MAILBOX_FLAG_READONLY);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen /* build QUOTAROOT reply and QUOTA reply for all quota roots */
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen quotaroot_reply = t_str_new(128);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen quota_reply = t_str_new(256);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen str_append(quotaroot_reply, "* QUOTAROOT ");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen imap_append_astring(quotaroot_reply, orig_mailbox);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen ret = 0;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen iter = quota_root_iter_init(box);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen while ((root = quota_root_iter_next(iter)) != NULL) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (quota_root_is_hidden(root))
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen continue;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen str_append_c(quotaroot_reply, ' ');
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen name = imap_quota_root_get_name(client->user, ns->owner, root);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen imap_append_astring(quotaroot_reply, name);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (quota_reply_write(quota_reply, client->user, ns->owner, root) < 0)
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen ret = -1;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen }
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen quota_root_iter_deinit(&iter);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen mailbox_free(&box);
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* send replies */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (ret < 0)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_tagline(cmd, "NO Internal quota calculation error.");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else if (str_len(quota_reply) == 0)
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_tagline(cmd, "OK No quota.");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen else {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_line(client, str_c(quotaroot_reply));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen o_stream_nsend(client->output, str_data(quota_reply),
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen str_len(quota_reply));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_tagline(cmd, "OK Getquotaroot completed.");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic bool
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenparse_quota_root(struct mail_user *user, const char *root_name,
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_user **owner_r, struct quota_root **root_r)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch const char *p;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
f32d0295c90ed810889504cdfa5e1a25a415f65fStephan Bosch *owner_r = user;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch *root_r = quota_root_lookup(user, root_name);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (*root_r != NULL || !user->admin)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return *root_r != NULL;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen /* we're an admin. see if there's a quota root for another user. */
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen p = strchr(root_name, QUOTA_USER_SEPARATOR);
e7dd5065d21c569e5e6ddd713bd345dadd1cf51dTimo Sirainen if (p != NULL) {
e7dd5065d21c569e5e6ddd713bd345dadd1cf51dTimo Sirainen *owner_r = mail_user_find(user, t_strdup_until(root_name, p));
d694a52bce62c52080c3f87a56dcf77030fd2712Timo Sirainen *root_r = *owner_r == NULL ? NULL :
d694a52bce62c52080c3f87a56dcf77030fd2712Timo Sirainen quota_root_lookup(*owner_r, p + 1);
009217abb57a24a4076092e8e4e165545747839eStephan Bosch }
009217abb57a24a4076092e8e4e165545747839eStephan Bosch return *root_r != NULL;
009217abb57a24a4076092e8e4e165545747839eStephan Bosch}
009217abb57a24a4076092e8e4e165545747839eStephan Bosch
009217abb57a24a4076092e8e4e165545747839eStephan Boschstatic bool cmd_getquota(struct client_command_context *cmd)
009217abb57a24a4076092e8e4e165545747839eStephan Bosch{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_user *owner;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct quota_root *root;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen const char *root_name;
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch string_t *quota_reply;
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch /* <quota root> */
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (!client_read_string_args(cmd, 1, &root_name))
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch return FALSE;
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch if (!parse_quota_root(cmd->client->user, root_name, &owner, &root)) {
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch client_send_tagline(cmd, "NO Quota root doesn't exist.");
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch return TRUE;
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch }
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch
c93aca832ee532010ead91b85fa9f614132e1be2Stephan Bosch quota_reply = t_str_new(128);
1093de32efb2a231949566d4bd8aa55a8f43fb70Timo Sirainen if (quota_reply_write(quota_reply, cmd->client->user, owner, root) < 0)
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen client_send_tagline(cmd, "NO Internal quota calculation error.");
ab281fc992907b6cf6c730f672dc3aa4c6685015Timo Sirainen else {
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen o_stream_nsend(cmd->client->output, str_data(quota_reply),
6d24551e169c0808695db35d7a228f1970a84c75Timo Sirainen str_len(quota_reply));
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_tagline(cmd, "OK Getquota completed.");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen}
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainenstatic bool cmd_setquota(struct client_command_context *cmd)
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen{
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen struct quota_root *root;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen struct mail_user *owner;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen const struct imap_arg *args, *list_args;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen const char *root_name, *name, *value_str, *error;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen uint64_t value;
1bf5c6c20f3d51f13d3240cfb46e471074c86276Timo Sirainen
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch /* <quota root> <resource limits> */
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (!client_read_args(cmd, 2, 0, &args))
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch return FALSE;
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch if (!imap_arg_get_astring(&args[0], &root_name) ||
36b072d84a9076c3c483bf710444a716e987ccc3Stephan Bosch !imap_arg_get_list(&args[1], &list_args)) {
8ce3071e80b9973230048ecadfcb073fb82cc69fTimo Sirainen client_send_command_error(cmd, "Invalid arguments.");
8ce3071e80b9973230048ecadfcb073fb82cc69fTimo Sirainen return TRUE;
8ce3071e80b9973230048ecadfcb073fb82cc69fTimo Sirainen }
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (!cmd->client->user->admin) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_tagline(cmd, "NO Quota can be changed only by admin.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen return TRUE;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e5acc283bf030b0b5c79ca4e52d315c516a299faPascal Volk if (!parse_quota_root(cmd->client->user, root_name, &owner, &root)) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_tagline(cmd, "NO Quota root doesn't exist.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen return TRUE;
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen }
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen for (; !IMAP_ARG_IS_EOL(list_args); list_args += 2) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen if (!imap_arg_get_atom(&list_args[0], &name) ||
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen !imap_arg_get_atom(&list_args[1], &value_str) ||
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen str_to_uint64(value_str, &value) < 0) {
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen client_send_command_error(cmd, "Invalid arguments.");
ce1a6c9b82117d253df9acd77e54ac84dd8a247eTimo Sirainen return TRUE;
2e2a1d720ed53490e8e5c5031e773d395bd5683dTimo Sirainen }
5a250816ffc4cc5db203f9410ea99b6601c7b91aTimo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (quota_set_resource(root, name, value, &error) < 0) {
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_command_error(cmd, error);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen }
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_send_tagline(cmd, "OK Setquota completed.");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen return TRUE;
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenstatic void imap_quota_client_created(struct client **client)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (mail_user_is_plugin_loaded((*client)->user, imap_quota_module))
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen client_add_capability(*client, "QUOTA");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen if (next_hook_client_created != NULL)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen next_hook_client_created(client);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainenvoid imap_quota_plugin_init(struct module *module)
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen{
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen command_register("GETQUOTAROOT", cmd_getquotaroot, 0);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen command_register("GETQUOTA", cmd_getquota, 0);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen command_register("SETQUOTA", cmd_setquota, 0);
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen imap_quota_module = module;
b8afdaa1bffe2f27cd4b02bf3bfbd2d297c8e648Timo Sirainen next_hook_client_created =
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen imap_client_created_hook_set(imap_quota_client_created);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenvoid imap_quota_plugin_deinit(void)
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen{
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen command_unregister("GETQUOTAROOT");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen command_unregister("GETQUOTA");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen command_unregister("SETQUOTA");
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen imap_client_created_hook_set(next_hook_client_created);
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen}
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen
ec23e16ed879e289d12c6e1a5f9745dd3979004aTimo Sirainenconst char *imap_quota_plugin_dependencies[] = { "quota", NULL };
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainenconst char imap_quota_plugin_binary_dependency[] = "imap";
e248fe370c4047cee921a91b48edc37944ab0526Timo Sirainen