[dovecot-cvs] dovecot/src/plugins/acl acl-api-private.h, 1.4, 1.5 acl-api.c, 1.4, 1.5 acl-api.h, 1.1, 1.2 acl-backend-vfile.c, 1.15, 1.16 acl-backend.c, 1.5, 1.6 acl-mailbox-list.c, 1.4, 1.5 acl-mailbox.c, 1.5, 1.6 acl-plugin.h, 1.4, 1.5 acl-storage.c, 1.5, 1.6

tss at dovecot.org tss at dovecot.org
Wed Apr 11 14:02:34 EEST 2007


Update of /var/lib/cvs/dovecot/src/plugins/acl
In directory talvi:/tmp/cvs-serv25636

Modified Files:
	acl-api-private.h acl-api.c acl-api.h acl-backend-vfile.c 
	acl-backend.c acl-mailbox-list.c acl-mailbox.c acl-plugin.h 
	acl-storage.c 
Log Message:
acl_backend is now tied to mailbox_list instead of mail_storage.



Index: acl-api-private.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-api-private.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- acl-api-private.h	28 Dec 2006 14:47:38 -0000	1.4
+++ acl-api-private.h	11 Apr 2007 11:02:31 -0000	1.5
@@ -9,6 +9,7 @@
 	void (*deinit)(struct acl_backend *backend);
 
 	struct acl_object *(*object_init)(struct acl_backend *backend,
+					  struct mail_storage *storage,
 					  const char *name);
 	void (*object_deinit)(struct acl_object *aclobj);
 
@@ -29,7 +30,7 @@
 	const char **groups;
 	unsigned int group_count;
 
-	struct mail_storage *storage;
+	struct mailbox_list *list;
 	struct acl_cache *cache;
 
 	struct acl_object *default_aclobj;

Index: acl-api.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-api.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- acl-api.c	28 Dec 2006 14:47:38 -0000	1.4
+++ acl-api.c	11 Apr 2007 11:02:31 -0000	1.5
@@ -2,22 +2,14 @@
 
 #include "lib.h"
 #include "hash.h"
-#include "mail-storage.h"
 #include "acl-cache.h"
 #include "acl-api-private.h"
 
 struct acl_object *acl_object_init_from_name(struct acl_backend *backend,
+					     struct mail_storage *storage,
 					     const char *name)
 {
-	return backend->v.object_init(backend, name);
-}
-
-struct acl_object *acl_object_init_from_mailbox(struct acl_backend *backend,
-						struct mailbox *box)
-{
-	i_assert(mailbox_get_storage(box) == backend->storage);
-
-	return acl_object_init_from_name(backend, mailbox_get_name(box));
+	return backend->v.object_init(backend, storage, name);
 }
 
 void acl_object_deinit(struct acl_object **_aclobj)

Index: acl-api.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-api.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- acl-api.h	27 Feb 2006 16:30:39 -0000	1.1
+++ acl-api.h	11 Apr 2007 11:02:31 -0000	1.2
@@ -1,8 +1,8 @@
 #ifndef __ACL_API_H
 #define __ACL_API_H
 
+struct mailbox_list;
 struct mail_storage;
-struct mailbox;
 struct acl_object;
 
 /* Show mailbox in mailbox list. Allow subscribing to it. */
@@ -73,7 +73,7 @@
    is NULL, it means the user is anonymous. Username and groups are matched
    case-sensitively. */
 struct acl_backend *
-acl_backend_init(const char *data, struct mail_storage *storage,
+acl_backend_init(const char *data, struct mailbox_list *list,
 		 const char *acl_username, const char *const *groups,
 		 const char *owner_username);
 void acl_backend_deinit(struct acl_backend **user);
@@ -90,9 +90,8 @@
 				      const char *right);
 
 struct acl_object *acl_object_init_from_name(struct acl_backend *backend,
+					     struct mail_storage *storage,
 					     const char *name);
-struct acl_object *acl_object_init_from_mailbox(struct acl_backend *backend,
-						struct mailbox *box);
 void acl_object_deinit(struct acl_object **aclobj);
 
 /* Returns 1 if we have the requested rights, 0 if not, or -1 if internal

Index: acl-backend-vfile.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-backend-vfile.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- acl-backend-vfile.c	11 Apr 2007 08:56:20 -0000	1.15
+++ acl-backend-vfile.c	11 Apr 2007 11:02:31 -0000	1.16
@@ -84,7 +84,7 @@
 
 	t_push();
 	tmp = t_strsplit(data, ":");
-	backend->global_dir = p_strdup(_backend->pool, *tmp);
+	backend->global_dir = p_strdup_empty(_backend->pool, *tmp);
 
 	while (*++tmp != NULL) {
 		if (strncmp(*tmp, "cache_secs=", 11) == 0)
@@ -113,37 +113,30 @@
 }
 
 static struct acl_object *
-acl_backend_vfile_object_init(struct acl_backend *_backend, const char *name)
+acl_backend_vfile_object_init(struct acl_backend *_backend,
+			      struct mail_storage *storage, const char *name)
 {
 	struct acl_backend_vfile *backend =
 		(struct acl_backend_vfile *)_backend;
 	struct acl_object_vfile *aclobj;
-	const char *control_dir, *dir;
+	const char *dir;
 	bool is_file;
 
 	aclobj = i_new(struct acl_object_vfile, 1);
 	aclobj->aclobj.backend = _backend;
 	aclobj->aclobj.name = i_strdup(name);
-	aclobj->global_path = *backend->global_dir == '\0' ? NULL :
+	aclobj->global_path = backend->global_dir == NULL ? NULL :
 		i_strconcat(backend->global_dir, "/", name, NULL);
 
-	control_dir =
-		mail_storage_get_mailbox_control_dir(_backend->storage, name);
-	dir = mail_storage_get_mailbox_path(_backend->storage, name, &is_file);
-	if (is_file) {
-		/* use control directory with mboxes */
-		dir = control_dir;
-	} else if (strcmp(control_dir, dir) != 0) {
-		/* FIXME: this is only for making sure people won't upgrade
-		   improperly. remove this check some day. */
-		const char *path;
-		struct stat st;
-
-		path = t_strconcat(control_dir, "/"ACL_FILENAME, NULL);
-		if (stat(path, &st) == 0) {
-			i_fatal("%s is no longer kept in control directory, "
-				"move it to the actual maildir (%s)",
-				path, dir);
+	if (storage == NULL) {
+		/* the default ACL for mailbox list */
+		dir = mailbox_list_get_path(_backend->list, NULL,
+					    MAILBOX_LIST_PATH_TYPE_DIR);
+	} else {
+		dir = mail_storage_get_mailbox_path(storage, name, &is_file);
+		if (is_file) {
+			dir = mailbox_list_get_path(_backend->list, name,
+					MAILBOX_LIST_PATH_TYPE_CONTROL);
 		}
 	}
 	aclobj->local_path = i_strconcat(dir, "/"ACL_FILENAME, NULL);
@@ -258,9 +251,7 @@
 	}
 
 	if (error != NULL) {
-		mail_storage_set_critical(aclobj->backend->storage,
-					  "ACL file %s line %u: %s",
-					  path, linenum, error);
+		i_error("ACL file %s line %u: %s", path, linenum, error);
 		t_pop();
 		return -1;
 	}
@@ -276,7 +267,6 @@
 		       struct acl_vfile_validity *validity, bool try_retry,
 		       bool *is_dir_r)
 {
-	struct mail_storage *storage = aclobj->backend->storage;
 	struct istream *input;
 	struct stat st;
 	const char *line;
@@ -296,7 +286,7 @@
 			validity->last_read_time = ioloop_time;
 			return 1;
 		}
-		mail_storage_set_critical(storage, "open(%s) failed: %m", path);
+		i_error("open(%s) failed: %m", path);
 		return -1;
 	}
 
@@ -306,8 +296,7 @@
 			return 0;
 		}
 
-		mail_storage_set_critical(storage,
-					  "fstat(%s) failed: %m", path);
+		i_error("fstat(%s) failed: %m", path);
 		(void)close(fd);
 		return -1;
 	}
@@ -337,8 +326,7 @@
 			ret = 0;
 		else {
 			ret = -1;
-			mail_storage_set_critical(storage,
-						  "read(%s) failed: %m", path);
+			i_error("read(%s) failed: %m", path);
 		}
 	}
 
@@ -348,8 +336,7 @@
 				ret = 0;
 			else {
 				ret = -1;
-				mail_storage_set_critical(storage,
-					"read(%s) failed: %m", path);
+				i_error("read(%s) failed: %m", path);
 			}
 		} else {
 			validity->last_read_time = ioloop_time;
@@ -363,8 +350,7 @@
 		if (errno == ESTALE && try_retry)
 			return 0;
 
-		mail_storage_set_critical(storage, "close(%s) failed: %m",
-					  path);
+		i_error("close(%s) failed: %m", path);
 		return -1;
 	}
 	return ret;
@@ -419,8 +405,7 @@
 			/* if the file used to exist, we have to re-read it */
 			return validity->last_mtime != 0;
 		} 
-		mail_storage_set_critical(aclobj->backend->storage,
-					  "stat(%s) failed: %m", path);
+		i_error("stat(%s) failed: %m", path);
 		return -1;
 	}
 

Index: acl-backend.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-backend.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- acl-backend.c	28 Dec 2006 14:47:38 -0000	1.5
+++ acl-backend.c	11 Apr 2007 11:02:31 -0000	1.6
@@ -26,7 +26,7 @@
 static const char *const non_owner_mailbox_rights[] = { NULL };
 
 struct acl_backend *
-acl_backend_init(const char *data, struct mail_storage *storage,
+acl_backend_init(const char *data, struct mailbox_list *list,
 		 const char *acl_username, const char *const *groups,
 		 const char *owner_username)
 {
@@ -54,7 +54,7 @@
 	backend = acl_backend_vfile.alloc();
 	backend->debug = debug;
 	backend->v = acl_backend_vfile;
-	backend->storage = storage;
+	backend->list = list;
 	backend->username = p_strdup(backend->pool, acl_username);
 	backend->owner_username = owner_username == NULL ? "" :
 		p_strdup(backend->pool, owner_username);
@@ -79,7 +79,7 @@
 				    storage_owner ? owner_mailbox_rights :
 				    non_owner_mailbox_rights);
 
-	backend->default_aclobj = acl_object_init_from_name(backend, "");
+	backend->default_aclobj = acl_object_init_from_name(backend, NULL, "");
 	return backend;
 }
 

Index: acl-mailbox-list.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-mailbox-list.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- acl-mailbox-list.c	29 Mar 2007 11:51:09 -0000	1.4
+++ acl-mailbox-list.c	11 Apr 2007 11:02:31 -0000	1.5
@@ -2,25 +2,51 @@
 
 #include "lib.h"
 #include "array.h"
+#include "mail-namespace.h"
 #include "mailbox-list-private.h"
 #include "acl-api-private.h"
 #include "acl-plugin.h"
 
+#include <stdlib.h>
+
 #define ACL_LIST_CONTEXT(obj) \
 	MODULE_CONTEXT(obj, acl_mailbox_list_module)
 
 struct acl_mailbox_list {
 	union mailbox_list_module_context module_ctx;
 
-	/* FIXME: this is wrong. multiple storages can use the same
-	   mailbox_list, so the whole ACL plugin probably needs redesigning.
-	   for now this is just kludged to work this way. */
-	struct mail_storage *storage;
+	struct acl_storage_rights_context rights;
 };
 
 static MODULE_CONTEXT_DEFINE_INIT(acl_mailbox_list_module,
 				  &mailbox_list_module_register);
 
+struct acl_backend *acl_mailbox_list_get_backend(struct mailbox_list *list)
+{
+	struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(list);
+
+	return alist->rights.backend;
+}
+
+const char *acl_mailbox_list_get_parent_mailbox_name(struct mailbox_list *list,
+						     const char *name)
+{
+	const char *p;
+	char sep;
+
+	sep = mailbox_list_get_hierarchy_sep(list);
+	p = strrchr(name, sep);
+	return p == NULL ? "" : t_strdup_until(name, p);
+}
+
+static int
+acl_mailbox_list_have_right(struct acl_mailbox_list *alist, const char *name,
+			    unsigned int acl_storage_right_idx, bool *can_see_r)
+{
+	return acl_storage_rights_ctx_have_right(&alist->rights, name,
+						 acl_storage_right_idx,
+						 can_see_r);
+}
 
 static struct mailbox_info *
 acl_mailbox_list_iter_next(struct mailbox_list_iterate_context *ctx)
@@ -34,8 +60,9 @@
 		if (info == NULL)
 			return NULL;
 
-		ret = acl_storage_have_right(alist->storage, info->name,
-					     ACL_STORAGE_RIGHT_LOOKUP, NULL);
+		ret = acl_mailbox_list_have_right(alist, info->name,
+						  ACL_STORAGE_RIGHT_LOOKUP,
+						  NULL);
 		if (ret > 0)
 			return info;
 		if (ret < 0) {
@@ -63,8 +90,8 @@
 	const char *parent;
 	int ret;
 
-	ret = acl_storage_have_right(alist->storage, name,
-				     ACL_STORAGE_RIGHT_LOOKUP, NULL);
+	ret = acl_mailbox_list_have_right(alist, name, ACL_STORAGE_RIGHT_LOOKUP,
+					  NULL);
 	if (ret < 0)
 		return -1;
 
@@ -85,10 +112,10 @@
 	case MAILBOX_NAME_NOINFERIORS:
 		/* have to check if we are allowed to see the parent */
 		t_push();
-		parent = acl_storage_get_parent_mailbox_name(alist->storage,
-							     name);
-		ret = acl_storage_have_right(alist->storage, parent,
-					     ACL_STORAGE_RIGHT_LOOKUP, NULL);
+		parent = acl_mailbox_list_get_parent_mailbox_name(list, name);
+		ret = acl_mailbox_list_have_right(alist, parent,
+						  ACL_STORAGE_RIGHT_LOOKUP,
+						  NULL);
 		t_pop();
 
 		if (ret < 0)
@@ -109,17 +136,17 @@
 	bool can_see;
 	int ret;
 
-	ret = acl_storage_have_right(alist->storage, name,
-				     ACL_STORAGE_RIGHT_DELETE, &can_see);
+	ret = acl_mailbox_list_have_right(alist, name, ACL_STORAGE_RIGHT_DELETE,
+					  &can_see);
 	if (ret <= 0) {
 		if (ret < 0)
 			return -1;
 		if (can_see) {
-			mail_storage_set_error(alist->storage,
+			mailbox_list_set_error(list,
 					       MAILBOX_LIST_ERR_NO_PERMISSION);
 		} else {
-			mail_storage_set_error(alist->storage,
-				MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name);
+			mailbox_list_set_error(list, t_strdup_printf(
+				MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, name));
 		}
 		return -1;
 	}
@@ -136,25 +163,25 @@
 	int ret;
 
 	/* renaming requires rights to delete the old mailbox */
-	ret = acl_storage_have_right(alist->storage, oldname,
-				     ACL_STORAGE_RIGHT_DELETE, &can_see);
+	ret = acl_mailbox_list_have_right(alist, oldname,
+					  ACL_STORAGE_RIGHT_DELETE, &can_see);
 	if (ret <= 0) {
 		if (ret < 0)
 			return -1;
 		if (can_see) {
-			mail_storage_set_error(alist->storage,
+			mailbox_list_set_error(list,
 					       MAILBOX_LIST_ERR_NO_PERMISSION);
 		} else {
-			mail_storage_set_error(alist->storage,
-				MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname);
+			mailbox_list_set_error(list, t_strdup_printf(
+				MAILBOX_LIST_ERR_MAILBOX_NOT_FOUND, oldname));
 		}
 		return 0;
 	}
 
 	/* and create the new one under the parent mailbox */
 	t_push();
-	ret = acl_storage_have_right(alist->storage,
-		acl_storage_get_parent_mailbox_name(alist->storage, newname),
+	ret = acl_mailbox_list_have_right(alist,
+		acl_mailbox_list_get_parent_mailbox_name(list, newname),
 		ACL_STORAGE_RIGHT_CREATE, NULL);
 	t_pop();
 
@@ -163,7 +190,7 @@
 			/* Note that if the mailbox didn't have LOOKUP
 			   permission, this not reveals to user the mailbox's
 			   existence. Can't help it. */
-			mail_storage_set_error(alist->storage,
+			mailbox_list_set_error(list,
 					       MAILBOX_LIST_ERR_NO_PERMISSION);
 		}
 		return -1;
@@ -175,10 +202,45 @@
 void acl_mailbox_list_created(struct mailbox_list *list)
 {
 	struct acl_mailbox_list *alist;
+	struct acl_backend *backend;
+	struct mail_namespace *ns;
+	enum mailbox_list_flags flags;
+	const char *acl_env, *current_username, *owner_username;
 
 	if (acl_next_hook_mailbox_list_created != NULL)
 		acl_next_hook_mailbox_list_created(list);
 
+	acl_env = getenv("ACL");
+	i_assert(acl_env != NULL);
+
+	owner_username = getenv("USER");
+	if (owner_username == NULL)
+		i_fatal("ACL: USER environment not set");
+
+	current_username = getenv("MASTER_USER");
+	if (current_username == NULL)
+		current_username = owner_username;
+
+	/* We don't care about the username for non-private mailboxes.
+	   It's used only when checking if we're the mailbox owner. We never
+	   are for shared/public mailboxes. */
+	ns = mailbox_list_get_namespace(list);
+	if (ns->type != NAMESPACE_PRIVATE)
+		owner_username = NULL;
+
+	/* FIXME: set groups */
+	backend = acl_backend_init(acl_env, list, current_username, NULL,
+				   owner_username);
+	if (backend == NULL)
+		i_fatal("ACL backend initialization failed");
+
+	flags = mailbox_list_get_flags(list);
+	if ((flags & MAILBOX_LIST_FLAG_FULL_FS_ACCESS) != 0) {
+		/* not necessarily, but safer to do this for now.. */
+		i_fatal("mail_full_filesystem_access=yes is "
+			"incompatible with ACLs");
+	}
+
 	alist = p_new(list->pool, struct acl_mailbox_list, 1);
 	alist->module_ctx.super = list->v;
 	list->v.iter_next = acl_mailbox_list_iter_next;
@@ -186,14 +248,7 @@
 	list->v.delete_mailbox = acl_mailbox_list_delete;
 	list->v.rename_mailbox = acl_mailbox_list_rename;
 
-	MODULE_CONTEXT_SET(list, acl_mailbox_list_module, alist);
-}
-
-void acl_mailbox_list_set_storage(struct mail_storage *storage)
-{
-	struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(storage->list);
-
-	i_assert(alist->storage == NULL);
+	acl_storage_rights_ctx_init(&alist->rights, backend);
 
-	alist->storage = storage;
+	MODULE_CONTEXT_SET(list, acl_mailbox_list_module, alist);
 }

Index: acl-mailbox.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-mailbox.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- acl-mailbox.c	29 Mar 2007 11:51:09 -0000	1.5
+++ acl-mailbox.c	11 Apr 2007 11:02:31 -0000	1.6
@@ -40,11 +40,13 @@
 	int ret;
 
 	ret = acl_object_have_right(abox->aclobj,
-				    astorage->acl_storage_right_idx[right_idx]);
+			astorage->rights.acl_storage_right_idx[right_idx]);
 	if (ret > 0)
 		return 1;
-	if (ret < 0)
+	if (ret < 0) {
+		mail_storage_set_internal_error(box->storage);
 		return -1;
+	}
 
 	mail_storage_set_error(box->storage, MAILBOX_LIST_ERR_NO_PERMISSION);
 	return 0;
@@ -210,7 +212,8 @@
 
 	abox = p_new(box->pool, struct acl_mailbox, 1);
 	abox->module_ctx.super = box->v;
-	abox->aclobj = acl_object_init_from_name(astorage->backend,
+	abox->aclobj = acl_object_init_from_name(astorage->rights.backend,
+						 box->storage,
 						 mailbox_get_name(box));
 	
 	box->v.close = acl_mailbox_close;

Index: acl-plugin.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-plugin.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- acl-plugin.h	29 Mar 2007 11:51:09 -0000	1.4
+++ acl-plugin.h	11 Apr 2007 11:02:31 -0000	1.5
@@ -21,13 +21,16 @@
 	ACL_STORAGE_RIGHT_COUNT
 };
 
-struct acl_mail_storage {
-	union mail_storage_module_context module_ctx;
-
+struct acl_storage_rights_context {
 	struct acl_backend *backend;
 	unsigned int acl_storage_right_idx[ACL_STORAGE_RIGHT_COUNT];
 };
 
+struct acl_mail_storage {
+	union mail_storage_module_context module_ctx;
+	struct acl_storage_rights_context rights;
+};
+
 extern void (*acl_next_hook_mail_storage_created)
 	(struct mail_storage *storage);
 extern void (*acl_next_hook_mailbox_list_created)(struct mailbox_list *list);
@@ -38,12 +41,16 @@
 
 struct mailbox *acl_mailbox_open_box(struct mailbox *box);
 
-const char *
-acl_storage_get_parent_mailbox_name(struct mail_storage *storage,
-				    const char *name);
-int acl_storage_have_right(struct mail_storage *storage, const char *name,
-			   unsigned int acl_storage_right_idx, bool *can_see_r);
-void acl_mailbox_list_set_storage(struct mail_storage *storage);
+void acl_storage_rights_ctx_init(struct acl_storage_rights_context *ctx,
+				 struct acl_backend *backend);
+int acl_storage_rights_ctx_have_right(struct acl_storage_rights_context *ctx,
+				      const char *name,
+				      unsigned int acl_storage_right_idx,
+				      bool *can_see_r);
+
+struct acl_backend *acl_mailbox_list_get_backend(struct mailbox_list *list);
+const char *acl_mailbox_list_get_parent_mailbox_name(struct mailbox_list *list,
+						     const char *name);
 
 void acl_plugin_init(void);
 void acl_plugin_deinit(void);

Index: acl-storage.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/plugins/acl/acl-storage.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- acl-storage.c	29 Mar 2007 11:51:09 -0000	1.5
+++ acl-storage.c	11 Apr 2007 11:02:31 -0000	1.6
@@ -4,11 +4,10 @@
 #include "array.h"
 #include "istream.h"
 #include "acl-api-private.h"
+#include "mail-namespace.h"
 #include "mailbox-list-private.h"
 #include "acl-plugin.h"
 
-#include <stdlib.h>
-
 struct acl_storage_module acl_storage_module =
 	MODULE_CONTEXT_INIT(&mail_storage_module_register);
 
@@ -25,15 +24,31 @@
 	MAIL_ACL_ADMIN
 };
 
-int acl_storage_have_right(struct mail_storage *storage, const char *name,
-			   unsigned int acl_storage_right_idx, bool *can_see_r)
+void acl_storage_rights_ctx_init(struct acl_storage_rights_context *ctx,
+				 struct acl_backend *backend)
 {
-	struct acl_mail_storage *astorage = ACL_CONTEXT(storage);
-	const unsigned int *idx_arr = astorage->acl_storage_right_idx;
+	unsigned int i;
+
+	ctx->backend = backend;
+	for (i = 0; i < ACL_STORAGE_RIGHT_COUNT; i++) {
+		ctx->acl_storage_right_idx[i] =
+			acl_backend_lookup_right(backend,
+						 acl_storage_right_names[i]);
+	}
+}
+
+int acl_storage_rights_ctx_have_right(struct acl_storage_rights_context *ctx,
+				      const char *name,
+				      unsigned int acl_storage_right_idx,
+				      bool *can_see_r)
+{
+	const unsigned int *idx_arr = ctx->acl_storage_right_idx;
+	struct mail_namespace *ns;
 	struct acl_object *aclobj;
 	int ret, ret2;
 
-	aclobj = acl_object_init_from_name(astorage->backend, name);
+	ns = mailbox_list_get_namespace(ctx->backend->list);
+	aclobj = acl_object_init_from_name(ctx->backend, ns->storage, name);
 	ret = acl_object_have_right(aclobj, idx_arr[acl_storage_right_idx]);
 
 	if (can_see_r != NULL) {
@@ -48,24 +63,28 @@
 	return ret;
 }
 
-const char *
-acl_storage_get_parent_mailbox_name(struct mail_storage *storage,
-				    const char *name)
+static int
+acl_storage_have_right(struct mail_storage *storage, const char *name,
+		       unsigned int acl_storage_right_idx, bool *can_see_r)
 {
-	const char *p;
-	char sep;
+	struct acl_mail_storage *astorage = ACL_CONTEXT(storage);
+	int ret;
 
-	sep = mail_storage_get_hierarchy_sep(storage);
-	p = strrchr(name, sep);
-	return p == NULL ? "" : t_strdup_until(name, p);
+	ret = acl_storage_rights_ctx_have_right(&astorage->rights, name,
+						acl_storage_right_idx,
+						can_see_r);
+	if (ret < 0) 
+		mail_storage_set_internal_error(storage);
+	return ret;
 }
 
 static void acl_storage_destroy(struct mail_storage *storage)
 {
 	struct acl_mail_storage *astorage = ACL_CONTEXT(storage);
 
-	acl_backend_deinit(&astorage->backend);
-	astorage->module_ctx.super.destroy(storage);
+	acl_backend_deinit(&astorage->rights.backend);
+	if (astorage->module_ctx.super.destroy != NULL)
+		astorage->module_ctx.super.destroy(storage);
 }
 
 static struct mailbox *
@@ -112,11 +131,12 @@
 			      bool directory)
 {
 	struct acl_mail_storage *astorage = ACL_CONTEXT(storage);
+	struct mailbox_list *list = mail_storage_get_list(storage);
 	int ret;
 
 	t_push();
 	ret = acl_storage_have_right(storage,
-			acl_storage_get_parent_mailbox_name(storage, name),
+			acl_mailbox_list_get_parent_mailbox_name(list, name),
 			ACL_STORAGE_RIGHT_CREATE, NULL);
 	t_pop();
 
@@ -139,50 +159,18 @@
 {
 	struct acl_mail_storage *astorage;
 	struct acl_backend *backend;
-	const char *acl_env, *user_env, *owner_username;
-	unsigned int i;
 
 	if (acl_next_hook_mail_storage_created != NULL)
 		acl_next_hook_mail_storage_created(storage);
 
-	acl_env = getenv("ACL");
-	user_env = getenv("MASTER_USER");
-	if (user_env == NULL)
-		user_env = getenv("USER");
-	i_assert(acl_env != NULL && user_env != NULL);
-
-	/* FIXME: set groups. owner_username isn't also correct here it's a
-	   per-mailbox thing. but we don't currently support shared mailboxes,
-	   so this will do for now.. */
-	owner_username =
-		(storage->flags & MAIL_STORAGE_FLAG_SHARED_NAMESPACE) == 0 ?
-		getenv("USER") : NULL;
-	backend = acl_backend_init(acl_env, storage, user_env, NULL,
-				   owner_username);
-	if (backend == NULL)
-		i_fatal("ACL backend initialization failed");
-
-	if ((storage->flags & MAIL_STORAGE_FLAG_FULL_FS_ACCESS) != 0) {
-		/* FIXME: not necessarily, but safer to do this for now.. */
-		i_fatal("mail_full_filesystem_access=yes is "
-			"incompatible with ACLs");
-	}
-
 	astorage = p_new(storage->pool, struct acl_mail_storage, 1);
 	astorage->module_ctx.super = storage->v;
-	astorage->backend = backend;
 	storage->v.destroy = acl_storage_destroy;
 	storage->v.mailbox_open = acl_mailbox_open;
 	storage->v.mailbox_create = acl_mailbox_create;
 
-	acl_mailbox_list_set_storage(storage);
-
-	/* build ACL right lookup table */
-	for (i = 0; i < ACL_STORAGE_RIGHT_COUNT; i++) {
-		astorage->acl_storage_right_idx[i] =
-			acl_backend_lookup_right(backend,
-						 acl_storage_right_names[i]);
-	}
+	backend = acl_mailbox_list_get_backend(mail_storage_get_list(storage));
+	acl_storage_rights_ctx_init(&astorage->rights, backend);
 
 	MODULE_CONTEXT_SET(storage, acl_storage_module, astorage);
 }



More information about the dovecot-cvs mailing list