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