dovecot-2.2: acl: Code cleanup by moving around the code and ren...

dovecot at dovecot.org dovecot at dovecot.org
Fri Jan 17 23:11:07 EET 2014


details:   http://hg.dovecot.org/dovecot-2.2/rev/a217a938f9ae
changeset: 17113:a217a938f9ae
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Jan 17 16:10:56 2014 -0500
description:
acl: Code cleanup by moving around the code and renaming functions.

diffstat:

 src/plugins/acl/Makefile.am                |    1 +
 src/plugins/acl/acl-api-private.h          |   11 +
 src/plugins/acl/acl-api.c                  |  225 ++++++++++++
 src/plugins/acl/acl-backend-vfile-update.c |  258 +++++++++++++
 src/plugins/acl/acl-backend-vfile.c        |  542 +---------------------------
 src/plugins/acl/acl-backend-vfile.h        |   20 +
 6 files changed, 539 insertions(+), 518 deletions(-)

diffs (truncated from 1200 to 300 lines):

diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/Makefile.am
--- a/src/plugins/acl/Makefile.am	Wed Jan 15 16:44:04 2014 -0500
+++ b/src/plugins/acl/Makefile.am	Fri Jan 17 16:10:56 2014 -0500
@@ -22,6 +22,7 @@
 	acl-backend.c \
 	acl-backend-vfile.c \
 	acl-backend-vfile-acllist.c \
+	acl-backend-vfile-update.c \
 	acl-cache.c \
 	acl-lookup-dict.c \
 	acl-mailbox.c \
diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-api-private.h
--- a/src/plugins/acl/acl-api-private.h	Wed Jan 15 16:44:04 2014 -0500
+++ b/src/plugins/acl/acl-api-private.h	Fri Jan 17 16:10:56 2014 -0500
@@ -92,5 +92,16 @@
 			     const char *id, const char *const *rights,
 			     const char **error_r);
 const char *acl_rights_export(const struct acl_rights *rights);
+int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2);
+
+const char *const *
+acl_right_names_parse(pool_t pool, const char *acl, const char **error_r);
+void acl_right_names_write(string_t *dest, const char *const *rights);
+void acl_right_names_merge(pool_t pool, const char *const **destp,
+			   const char *const *src, bool dup_strings);
+bool acl_right_names_modify(pool_t pool,
+			    const char *const **rightsp,
+			    const char *const *modify_rights,
+			    enum acl_modify_mode modify_mode);
 
 #endif
diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-api.c
--- a/src/plugins/acl/acl-api.c	Wed Jan 15 16:44:04 2014 -0500
+++ b/src/plugins/acl/acl-api.c	Fri Jan 17 16:10:56 2014 -0500
@@ -9,6 +9,26 @@
 #include "acl-cache.h"
 #include "acl-api-private.h"
 
+struct acl_letter_map {
+	char letter;
+	const char *name;
+};
+
+static const struct acl_letter_map acl_letter_map[] = {
+	{ 'l', MAIL_ACL_LOOKUP },
+	{ 'r', MAIL_ACL_READ },
+	{ 'w', MAIL_ACL_WRITE },
+	{ 's', MAIL_ACL_WRITE_SEEN },
+	{ 't', MAIL_ACL_WRITE_DELETED },
+	{ 'i', MAIL_ACL_INSERT },
+	{ 'p', MAIL_ACL_POST },
+	{ 'e', MAIL_ACL_EXPUNGE },
+	{ 'k', MAIL_ACL_CREATE },
+	{ 'x', MAIL_ACL_DELETE },
+	{ 'a', MAIL_ACL_ADMIN },
+	{ '\0', NULL }
+};
+
 struct acl_object *acl_object_init_from_name(struct acl_backend *backend,
 					     const char *name)
 {
@@ -313,6 +333,23 @@
 	return str_c(str);
 }
 
+int acl_rights_cmp(const struct acl_rights *r1, const struct acl_rights *r2)
+{
+	int ret;
+
+	if (r1->global != r2->global) {
+		/* globals have higher priority than locals */
+		return r1->global ? 1 : -1;
+	}
+
+	ret = r1->id_type - r2->id_type;
+	if (ret != 0)
+		return ret;
+
+	return null_strcmp(r1->identifier, r2->identifier);
+}
+
+
 bool acl_rights_has_nonowner_lookup_changes(const struct acl_rights *rights)
 {
 	const char *const *p;
@@ -358,3 +395,191 @@
 	}
 	return 0;
 }
+
+static const char *const *
+acl_right_names_alloc(pool_t pool, ARRAY_TYPE(const_string) *rights_arr,
+		      bool dup_strings)
+{
+	const char **ret, *const *rights;
+	unsigned int i, dest, count;
+
+	/* sort the rights first so we can easily drop duplicates */
+	array_sort(rights_arr, i_strcmp_p);
+
+	/* @UNSAFE */
+	rights = array_get(rights_arr, &count);
+	ret = p_new(pool, const char *, count + 1);
+	if (count > 0) {
+		ret[0] = rights[0];
+		for (i = dest = 1; i < count; i++) {
+			if (strcmp(rights[i-1], rights[i]) != 0)
+				ret[dest++] = rights[i];
+		}
+		ret[dest] = NULL;
+		if (dup_strings) {
+			for (i = 0; i < dest; i++)
+				ret[i] = p_strdup(pool, ret[i]);
+		}
+	}
+	return ret;
+}
+
+const char *const *
+acl_right_names_parse(pool_t pool, const char *acl, const char **error_r)
+{
+	ARRAY_TYPE(const_string) rights;
+	const char *const *names;
+	unsigned int i;
+
+	/* parse IMAP ACL list */
+	while (*acl == ' ' || *acl == '\t')
+		acl++;
+
+	t_array_init(&rights, 64);
+	while (*acl != '\0' && *acl != ' ' && *acl != '\t' && *acl != ':') {
+		for (i = 0; acl_letter_map[i].letter != '\0'; i++) {
+			if (acl_letter_map[i].letter == *acl)
+				break;
+		}
+
+		if (acl_letter_map[i].letter == '\0') {
+			*error_r = t_strdup_printf("Unknown ACL '%c'", *acl);
+			return NULL;
+		}
+
+		array_append(&rights, &acl_letter_map[i].name, 1);
+		acl++;
+	}
+	while (*acl == ' ' || *acl == '\t') acl++;
+
+	if (*acl != '\0') {
+		/* parse our own extended ACLs */
+		if (*acl != ':') {
+			*error_r = "Missing ':' prefix in ACL extensions";
+			return NULL;
+		}
+
+		names = t_strsplit_spaces(acl + 1, ", \t");
+		for (; *names != NULL; names++) {
+			const char *name = p_strdup(pool, *names);
+			array_append(&rights, &name, 1);
+		}
+	}
+
+	return acl_right_names_alloc(pool, &rights, FALSE);
+}
+
+void acl_right_names_write(string_t *dest, const char *const *rights)
+{
+	char c2[2];
+	unsigned int i, j, pos;
+
+	c2[1] = '\0';
+	pos = str_len(dest);
+	for (i = 0; rights[i] != NULL; i++) {
+		/* use letters if possible */
+		for (j = 0; acl_letter_map[j].name != NULL; j++) {
+			if (strcmp(rights[i], acl_letter_map[j].name) == 0) {
+				c2[0] = acl_letter_map[j].letter;
+				str_insert(dest, pos, c2);
+				pos++;
+				break;
+			}
+		}
+		if (acl_letter_map[j].name == NULL) {
+			/* fallback to full name */
+			str_append_c(dest, ' ');
+			str_append(dest, rights[i]);
+		}
+	}
+	if (pos + 1 < str_len(dest)) {
+		c2[0] = ':';
+		str_insert(dest, pos + 1, c2);
+	}
+}
+
+void acl_right_names_merge(pool_t pool, const char *const **destp,
+			   const char *const *src, bool dup_strings)
+{
+	const char *const *dest = *destp;
+	ARRAY_TYPE(const_string) rights;
+	unsigned int i;
+
+	t_array_init(&rights, 64);
+	if (dest != NULL) {
+		for (i = 0; dest[i] != NULL; i++)
+			array_append(&rights, &dest[i], 1);
+	}
+	if (src != NULL) {
+		for (i = 0; src[i] != NULL; i++)
+			array_append(&rights, &src[i], 1);
+	}
+
+	*destp = acl_right_names_alloc(pool, &rights, dup_strings);
+}
+
+bool acl_right_names_modify(pool_t pool,
+			    const char *const **rightsp,
+			    const char *const *modify_rights,
+			    enum acl_modify_mode modify_mode)
+{
+	const char *const *old_rights = *rightsp;
+	const char *const *new_rights = NULL;
+	const char *null = NULL;
+	ARRAY_TYPE(const_string) rights;
+	unsigned int i, j;
+
+	if (modify_rights == NULL && modify_mode != ACL_MODIFY_MODE_CLEAR) {
+		/* nothing to do here */
+		return FALSE;
+	}
+
+	switch (modify_mode) {
+	case ACL_MODIFY_MODE_REMOVE:
+		if (old_rights == NULL || *old_rights == NULL) {
+			/* nothing to do */
+			return FALSE;
+		}
+		t_array_init(&rights, 64);
+		for (i = 0; old_rights[i] != NULL; i++) {
+			for (j = 0; modify_rights[j] != NULL; j++) {
+				if (strcmp(old_rights[i], modify_rights[j]) == 0)
+					break;
+			}
+			if (modify_rights[j] == NULL)
+				array_append(&rights, &old_rights[i], 1);
+		}
+		new_rights = &null;
+		modify_rights = array_count(&rights) == 0 ? NULL :
+			array_idx(&rights, 0);
+		acl_right_names_merge(pool, &new_rights, modify_rights, TRUE);
+		break;
+	case ACL_MODIFY_MODE_ADD:
+		new_rights = old_rights;
+		acl_right_names_merge(pool, &new_rights, modify_rights, TRUE);
+		break;
+	case ACL_MODIFY_MODE_REPLACE:
+		new_rights = &null;
+		acl_right_names_merge(pool, &new_rights, modify_rights, TRUE);
+		break;
+	case ACL_MODIFY_MODE_CLEAR:
+		if (*rightsp == NULL) {
+			/* ACL didn't exist before either */
+			return FALSE;
+		}
+		*rightsp = NULL;
+		return TRUE;
+	}
+	i_assert(new_rights != NULL);
+	*rightsp = new_rights;
+
+	if (old_rights == NULL)
+		return new_rights[0] != NULL;
+
+	/* see if anything changed */
+	for (i = 0; old_rights[i] != NULL && new_rights[i] != NULL; i++) {
+		if (strcmp(old_rights[i], new_rights[i]) != 0)
+			return TRUE;
+	}
+	return old_rights[i] != NULL || new_rights[i] != NULL;
+}
diff -r 9735c6fb7e39 -r a217a938f9ae src/plugins/acl/acl-backend-vfile-update.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/plugins/acl/acl-backend-vfile-update.c	Fri Jan 17 16:10:56 2014 -0500
@@ -0,0 +1,258 @@
+/* Copyright (c) 2006-2014 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "bsearch-insert-pos.h"
+#include "ioloop.h"
+#include "str.h"
+#include "strescape.h"
+#include "file-dotlock.h"
+#include "ostream.h"
+#include "mailbox-list.h"
+#include "mail-storage-private.h"
+#include "acl-cache.h"
+#include "acl-backend-vfile.h"
+
+#include <utime.h>
+
+static struct dotlock_settings dotlock_set = {
+	.timeout = 30,


More information about the dovecot-cvs mailing list