dovecot-1.2: imap-acl: GETACL: Convert "owner" to the actual use...

dovecot at dovecot.org dovecot at dovecot.org
Fri Feb 20 23:26:47 EET 2009


details:   http://hg.dovecot.org/dovecot-1.2/rev/be1d1c722c92
changeset: 8756:be1d1c722c92
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Feb 20 16:26:41 2009 -0500
description:
imap-acl: GETACL: Convert "owner" to the actual username whenever possible.

diffstat:

6 files changed, 77 insertions(+), 28 deletions(-)
src/plugins/acl/acl-api-private.h      |    1 
src/plugins/acl/acl-api.c              |    7 +++
src/plugins/acl/acl-api.h              |    7 +++
src/plugins/acl/acl-backend-vfile.c    |   27 +-------------
src/plugins/acl/acl-backend.c          |    5 ++
src/plugins/imap-acl/imap-acl-plugin.c |   58 ++++++++++++++++++++++++++++++--

diffs (216 lines):

diff -r 2579345e877f -r be1d1c722c92 src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/acl/acl-api-private.h	Fri Feb 20 16:26:41 2009 -0500
@@ -73,7 +73,6 @@ struct acl_object_list_iter {
 	struct acl_object *aclobj;
 
 	unsigned int idx;
-	unsigned int returned_owner:1;
 	unsigned int failed:1;
 };
 
diff -r 2579345e877f -r be1d1c722c92 src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/acl/acl-api.c	Fri Feb 20 16:26:41 2009 -0500
@@ -124,6 +124,13 @@ int acl_object_get_my_rights(struct acl_
 	return ret;
 }
 
+const char *const *acl_object_get_default_rights(struct acl_object *aclobj)
+{
+	return acl_backend_mask_get_names(aclobj->backend,
+					  aclobj->backend->default_aclmask,
+					  pool_datastack_create());
+}
+
 int acl_object_update(struct acl_object *aclobj,
 		      const struct acl_rights_update *update)
 {
diff -r 2579345e877f -r be1d1c722c92 src/plugins/acl/acl-api.h
--- a/src/plugins/acl/acl-api.h	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/acl/acl-api.h	Fri Feb 20 16:26:41 2009 -0500
@@ -92,6 +92,11 @@ acl_backend_init(const char *data, struc
 		 const char *acl_username, const char *const *groups,
 		 bool owner);
 void acl_backend_deinit(struct acl_backend **backend);
+
+/* Returns the acl_username passed to acl_backend_init(). Note that with
+   anonymous users NULL is returned. */
+const char *acl_backend_get_acl_username(struct acl_backend *backend);
+
 /* Returns TRUE if user isn't anonymous. */
 bool acl_backend_user_is_authenticated(struct acl_backend *backend);
 /* Returns TRUE if user owns the storage. */
@@ -128,6 +133,8 @@ int acl_object_have_right(struct acl_obj
 /* Returns 0 = ok, -1 = internal error */
 int acl_object_get_my_rights(struct acl_object *aclobj, pool_t pool,
 			     const char *const **rights_r);
+/* Returns the default rights for the object. */
+const char *const *acl_object_get_default_rights(struct acl_object *aclobj);
 
 /* Update ACL of given object. */
 int acl_object_update(struct acl_object *aclobj,
diff -r 2579345e877f -r be1d1c722c92 src/plugins/acl/acl-backend-vfile.c
--- a/src/plugins/acl/acl-backend-vfile.c	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/acl/acl-backend-vfile.c	Fri Feb 20 16:26:41 2009 -0500
@@ -1127,7 +1127,6 @@ acl_backend_vfile_object_list_init(struc
 	struct acl_object_vfile *aclobj =
 		(struct acl_object_vfile *)_aclobj;
 	struct acl_object_list_iter *iter;
-	struct mail_namespace *ns;
 
 	iter = i_new(struct acl_object_list_iter, 1);
 	iter->aclobj = _aclobj;
@@ -1138,12 +1137,6 @@ acl_backend_vfile_object_list_init(struc
 		acl_cache_flush(_aclobj->backend->cache, _aclobj->name);
 	}
 
-	/* be sure to return owner for private namespaces.
-	   (other namespaces don't have an owner) */
-	ns = mailbox_list_get_namespace(_aclobj->backend->list);
-	if (ns->type != NAMESPACE_PRIVATE)
-		iter->returned_owner = TRUE;
-
 	if (_aclobj->backend->v.object_refresh_cache(_aclobj) < 0)
 		iter->failed = TRUE;
 	return iter;
@@ -1157,26 +1150,10 @@ acl_backend_vfile_object_list_next(struc
 		(struct acl_object_vfile *)iter->aclobj;
 	const struct acl_rights *rights;
 
-	if (iter->idx == array_count(&aclobj->rights)) {
-		struct acl_backend *backend = iter->aclobj->backend;
-
-		if (iter->returned_owner)
-			return 0;
-
-		/* return missing owner based on the default ACLs */
-		iter->returned_owner = TRUE;
-		memset(rights_r, 0, sizeof(*rights_r));
-		rights_r->id_type = ACL_ID_OWNER;
-		rights_r->rights =
-			acl_backend_mask_get_names(backend,
-						   backend->default_aclmask,
-						   pool_datastack_create());
-		return 1;
-	}
+	if (iter->idx == array_count(&aclobj->rights))
+		return 0;
 
 	rights = array_idx(&aclobj->rights, iter->idx++);
-	if (rights->id_type == ACL_ID_OWNER && rights->rights != NULL)
-		iter->returned_owner = TRUE;
 	*rights_r = *rights;
 	return 1;
 }
diff -r 2579345e877f -r be1d1c722c92 src/plugins/acl/acl-backend.c
--- a/src/plugins/acl/acl-backend.c	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/acl/acl-backend.c	Fri Feb 20 16:26:41 2009 -0500
@@ -95,6 +95,11 @@ void acl_backend_deinit(struct acl_backe
 	backend->v.deinit(backend);
 }
 
+const char *acl_backend_get_acl_username(struct acl_backend *backend)
+{
+	return backend->username;
+}
+
 bool acl_backend_user_is_authenticated(struct acl_backend *backend)
 {
 	return backend->username != NULL;
diff -r 2579345e877f -r be1d1c722c92 src/plugins/imap-acl/imap-acl-plugin.c
--- a/src/plugins/imap-acl/imap-acl-plugin.c	Fri Feb 20 15:47:39 2009 -0500
+++ b/src/plugins/imap-acl/imap-acl-plugin.c	Fri Feb 20 16:26:41 2009 -0500
@@ -162,16 +162,51 @@ imap_acl_write_right(string_t *dest, str
 	imap_acl_write_rights_list(dest, rights);
 }
 
-static int imap_acl_write_aclobj(string_t *dest, struct acl_object *aclobj)
+static int
+imap_acl_write_aclobj(string_t *dest, struct acl_backend *backend,
+		      struct acl_object *aclobj, bool convert_owner)
 {
 	struct acl_object_list_iter *iter;
 	struct acl_rights rights;
 	string_t *tmp;
+	const char *username;
+	unsigned int orig_len = str_len(dest);
+	bool owner, seen_owner = FALSE, seen_positive_owner = FALSE;
 	int ret;
+
+	username = acl_backend_get_acl_username(backend);
+	if (username == NULL)
+		convert_owner = FALSE;
 
 	tmp = t_str_new(128);
 	iter = acl_object_list_init(aclobj);
 	while ((ret = acl_object_list_next(iter, &rights)) > 0) {
+		if (rights.id_type == ACL_ID_USER &&
+		    acl_backend_user_name_equals(backend, rights.identifier))
+			owner = TRUE;
+		else if (rights.id_type == ACL_ID_OWNER) {
+			owner = TRUE;
+			if (convert_owner) {
+				rights.id_type = ACL_ID_USER;
+				rights.identifier = username;
+			}
+		} else {
+			owner = FALSE;
+		}
+
+		if (owner) {
+			if (seen_owner && convert_owner) {
+				/* oops, we have both owner and user=myself.
+				   can't do the conversion, so try again. */
+				str_truncate(dest, orig_len);
+				return imap_acl_write_aclobj(dest, backend,
+							     aclobj, FALSE);
+			}
+			seen_owner = TRUE;
+			if (rights.rights != NULL)
+				seen_positive_owner = TRUE;
+		}
+
 		if (rights.rights != NULL) {
 			str_append_c(dest, ' ');
 			imap_acl_write_right(dest, tmp, &rights, FALSE);
@@ -182,11 +217,28 @@ static int imap_acl_write_aclobj(string_
 		}
 	}
 	acl_object_list_deinit(&iter);
+
+	if (!seen_positive_owner && username != NULL) {
+		/* no positive owner rights returned, write default ACLs */
+		memset(&rights, 0, sizeof(rights));
+		if (!convert_owner) {
+			rights.id_type = ACL_ID_OWNER;
+		} else {
+			rights.id_type = ACL_ID_USER;
+			rights.identifier = username;
+		}
+		rights.rights = acl_object_get_default_rights(aclobj);
+		if (rights.rights != NULL) {
+			str_append_c(dest, ' ');
+			imap_acl_write_right(dest, tmp, &rights, FALSE);
+		}
+	}
 	return ret;
 }
 
 static bool cmd_getacl(struct client_command_context *cmd)
 {
+	struct acl_backend *backend;
 	struct mailbox *box;
 	const char *mailbox;
 	string_t *str;
@@ -207,7 +259,9 @@ static bool cmd_getacl(struct client_com
 	imap_quote_append_string(str, mailbox, FALSE);
 	len = str_len(str);
 
-	ret = imap_acl_write_aclobj(str, acl_mailbox_get_aclobj(box));
+	backend = acl_storage_get_backend(mailbox_get_storage(box));
+	ret = imap_acl_write_aclobj(str, backend,
+				    acl_mailbox_get_aclobj(box), TRUE);
 	if (ret == 0) {
 		client_send_line(cmd->client, str_c(str));
 		client_send_tagline(cmd, "OK Getacl completed.");


More information about the dovecot-cvs mailing list