dovecot-1.2: Quota works now properly with shared mailboxes.
dovecot at dovecot.org
dovecot at dovecot.org
Fri Nov 21 19:46:23 EET 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/e4f319453cb2
changeset: 8470:e4f319453cb2
user: Timo Sirainen <tss at iki.fi>
date: Fri Nov 21 19:45:57 2008 +0200
description:
Quota works now properly with shared mailboxes.
diffstat:
5 files changed, 74 insertions(+), 17 deletions(-)
src/lib-storage/mail-user.c | 11 +++++
src/lib-storage/mail-user.h | 6 ++
src/plugins/imap-quota/imap-quota-plugin.c | 61 ++++++++++++++++++++++------
src/plugins/quota/quota-storage.c | 6 +-
src/plugins/quota/quota.c | 7 +--
diffs (233 lines):
diff -r e2ec45b71119 -r e4f319453cb2 src/lib-storage/mail-user.c
--- a/src/lib-storage/mail-user.c Fri Nov 21 19:45:22 2008 +0200
+++ b/src/lib-storage/mail-user.c Fri Nov 21 19:45:57 2008 +0200
@@ -55,6 +55,17 @@ void mail_user_unref(struct mail_user **
*_user = NULL;
if (--user->refcount == 0)
user->v.deinit(user);
+}
+
+struct mail_user *mail_user_find(struct mail_user *user, const char *name)
+{
+ struct mail_namespace *ns;
+
+ for (ns = user->namespaces; ns != NULL; ns = ns->next) {
+ if (ns->owner != NULL && strcmp(ns->owner->username, name) == 0)
+ return ns->owner;
+ }
+ return NULL;
}
void mail_user_set_home(struct mail_user *user, const char *home)
diff -r e2ec45b71119 -r e4f319453cb2 src/lib-storage/mail-user.h
--- a/src/lib-storage/mail-user.h Fri Nov 21 19:45:22 2008 +0200
+++ b/src/lib-storage/mail-user.h Fri Nov 21 19:45:57 2008 +0200
@@ -23,6 +23,9 @@ struct mail_user {
/* Either home is set or there is no home for the user. */
unsigned int home_looked_up:1;
+ /* User is an administrator. Allow operations not normally allowed
+ for other people. */
+ unsigned int admin:1;
};
struct mail_user_module_register {
@@ -45,6 +48,9 @@ void mail_user_ref(struct mail_user *use
void mail_user_ref(struct mail_user *user);
void mail_user_unref(struct mail_user **user);
+/* Find another user from the given user's namespaces. */
+struct mail_user *mail_user_find(struct mail_user *user, const char *name);
+
/* Specify the user's home directory. This should be called also when it's
known that the user doesn't have a home directory to avoid the internal
lookup. */
diff -r e2ec45b71119 -r e4f319453cb2 src/plugins/imap-quota/imap-quota-plugin.c
--- a/src/plugins/imap-quota/imap-quota-plugin.c Fri Nov 21 19:45:22 2008 +0200
+++ b/src/plugins/imap-quota/imap-quota-plugin.c Fri Nov 21 19:45:57 2008 +0200
@@ -3,6 +3,7 @@
#include "common.h"
#include "str.h"
#include "imap-quote.h"
+#include "mail-namespace.h"
#include "commands.h"
#include "quota.h"
#include "quota-plugin.h"
@@ -10,12 +11,28 @@
#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)
-{
- const char *const *list;
+quota_send(struct client_command_context *cmd, struct mail_user *owner,
+ struct quota_root *root)
+{
+ const char *name, *const *list;
string_t *str;
unsigned int i;
uint64_t value, limit;
@@ -23,7 +40,8 @@ quota_send(struct client_command_context
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);
@@ -47,11 +65,13 @@ quota_send(struct client_command_context
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> */
@@ -71,9 +91,15 @@ static bool cmd_getquotaroot(struct clie
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;
}
@@ -85,15 +111,16 @@ static bool cmd_getquotaroot(struct clie
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);
@@ -103,8 +130,9 @@ static bool cmd_getquotaroot(struct clie
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))
@@ -116,12 +144,23 @@ static bool cmd_getquota(struct client_c
}
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;
}
diff -r e2ec45b71119 -r e4f319453cb2 src/plugins/quota/quota-storage.c
--- a/src/plugins/quota/quota-storage.c Fri Nov 21 19:45:22 2008 +0200
+++ b/src/plugins/quota/quota-storage.c Fri Nov 21 19:45:57 2008 +0200
@@ -524,10 +524,10 @@ void quota_mail_storage_created(struct m
MODULE_CONTEXT_SET_SELF(storage, quota_storage_module, qstorage);
- if (storage->ns->type == NAMESPACE_PRIVATE &&
+ if (storage->ns->owner != NULL &&
(storage->ns->flags & NAMESPACE_FLAG_INTERNAL) == 0) {
- /* register to user's quota roots */
- quota = quota_get_mail_user_quota(storage->ns->user);
+ /* register to owner's quota roots */
+ quota = quota_get_mail_user_quota(storage->ns->owner);
quota_add_user_storage(quota, storage);
}
diff -r e2ec45b71119 -r e4f319453cb2 src/plugins/quota/quota.c
--- a/src/plugins/quota/quota.c Fri Nov 21 19:45:22 2008 +0200
+++ b/src/plugins/quota/quota.c Fri Nov 21 19:45:57 2008 +0200
@@ -524,7 +524,8 @@ void quota_remove_user_storage(struct ma
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;
@@ -579,7 +580,7 @@ struct quota_root_iter *
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);
@@ -717,7 +718,7 @@ int quota_set_resource(struct quota_root
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);
More information about the dovecot-cvs
mailing list