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