#include "common.h"
#include "str.h"
#include "imap-quote.h"
+#include "mail-namespace.h"
#include "commands.h"
#include "quota.h"
#include "quota-plugin.h"
#include <stdlib.h>
+#define QUOTA_USER_SEPARATOR ':'
+
const char *imap_quota_plugin_version = PACKAGE_VERSION;
+static const char *
+imap_quota_root_get_name(struct mail_user *user, struct mail_user *owner,
+ struct quota_root *root)
+{
+ const char *name;
+
+ name = quota_root_get_name(root);
+ if (user == owner)
+ return name;
+ return t_strdup_printf("%s%c%s", owner->username,
+ QUOTA_USER_SEPARATOR, name);
+}
+
static void
-quota_send(struct client_command_context *cmd, struct quota_root *root)
+quota_send(struct client_command_context *cmd, struct mail_user *owner,
+ struct quota_root *root)
{
- const char *const *list;
+ const char *name, *const *list;
string_t *str;
unsigned int i;
uint64_t value, limit;
str = t_str_new(128);
str_append(str, "* QUOTA ");
- imap_quote_append_string(str, quota_root_get_name(root), FALSE);
+ name = imap_quota_root_get_name(cmd->client->user, owner, root);
+ imap_quote_append_string(str, name, FALSE);
str_append(str, " (");
list = quota_root_get_resources(root);
static bool cmd_getquotaroot(struct client_command_context *cmd)
{
+ struct client *client = cmd->client;
struct mail_storage *storage;
+ struct mail_namespace *ns;
struct mailbox *box;
struct quota_root_iter *iter;
struct quota_root *root;
- const char *orig_mailbox, *mailbox;
+ const char *orig_mailbox, *mailbox, *name;
string_t *str;
/* <mailbox> */
return TRUE;
}
- if (quota_set == NULL) {
+ ns = mail_storage_get_namespace(storage);
+ if (quota_set == NULL || ns->owner == NULL) {
mailbox_close(&box);
client_send_tagline(cmd, "OK No quota.");
return TRUE;
}
+ if (ns->owner != client->user && !client->user->admin) {
+ mailbox_close(&box);
+ client_send_tagline(cmd, "NO Not showing other users' quota.");
+ return TRUE;
+ }
/* send QUOTAROOT reply */
str = t_str_new(128);
iter = quota_root_iter_init(box);
while ((root = quota_root_iter_next(iter)) != NULL) {
str_append_c(str, ' ');
- imap_quote_append_string(str, quota_root_get_name(root), FALSE);
+ name = imap_quota_root_get_name(client->user, ns->owner, root);
+ imap_quote_append_string(str, name, FALSE);
}
quota_root_iter_deinit(&iter);
- client_send_line(cmd->client, str_c(str));
+ client_send_line(client, str_c(str));
/* send QUOTA reply for each quotaroot */
iter = quota_root_iter_init(box);
while ((root = quota_root_iter_next(iter)) != NULL)
- quota_send(cmd, root);
+ quota_send(cmd, ns->owner, root);
quota_root_iter_deinit(&iter);
mailbox_close(&box);
static bool cmd_getquota(struct client_command_context *cmd)
{
- const char *root_name;
+ struct mail_user *owner = cmd->client->user;
struct quota_root *root;
+ const char *root_name, *p;
/* <quota root> */
if (!client_read_string_args(cmd, 1, &root_name))
}
root = quota_root_lookup(cmd->client->user, root_name);
+ if (root == NULL && cmd->client->user->admin) {
+ /* we're an admin. see if there's a quota root for another
+ user. */
+ p = strchr(root_name, QUOTA_USER_SEPARATOR);
+ if (p != NULL) {
+ owner = mail_user_find(cmd->client->user,
+ t_strdup_until(root_name, p));
+ root = owner == NULL ? NULL :
+ quota_root_lookup(owner, p + 1);
+ }
+ }
if (root == NULL) {
client_send_tagline(cmd, "NO Quota root doesn't exist.");
return TRUE;
}
- quota_send(cmd, root);
+ quota_send(cmd, owner, root);
client_send_tagline(cmd, "OK Getquota completed.");
return TRUE;
}
struct mail_storage *const *storages;
unsigned int i, count;
- quota = quota_get_mail_user_quota(storage->ns->user);
+ quota = storage->ns->owner == NULL ? NULL :
+ quota_get_mail_user_quota(storage->ns->owner);
if (quota == NULL) {
/* no quota for this storage */
return;
struct quota_root_iter *
quota_root_iter_init(struct mailbox *box)
{
- struct mail_user *user = box->storage->ns->user;
+ struct mail_user *user = box->storage->ns->owner;
struct quota_root_iter *iter;
iter = i_new(struct quota_root_iter, 1);
struct quota_transaction_context *quota_transaction_begin(struct mailbox *box)
{
- struct mail_user *user = box->storage->ns->user;
+ struct mail_user *user = box->storage->ns->owner;
struct quota_transaction_context *ctx;
ctx = i_new(struct quota_transaction_context, 1);