From 37c72fa0cd3f1d74d79b64afb3fb6da5ffd4fe3a Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sat, 3 Sep 2016 13:14:29 +0300 Subject: [PATCH] acl-plugin: Make iterators more conforming The *_next functions return true/false, deinit will report errors and end result. --- src/plugins/acl/acl-api-private.h | 21 ++++++++---- src/plugins/acl/acl-api.c | 37 +++++++++++++-------- src/plugins/acl/acl-api.h | 9 ++--- src/plugins/acl/acl-attributes.c | 11 +++--- src/plugins/acl/acl-backend-vfile-acllist.c | 21 +++++++++--- src/plugins/acl/acl-backend-vfile.h | 4 +-- src/plugins/acl/doveadm-acl.c | 10 +++--- 7 files changed, 69 insertions(+), 44 deletions(-) diff --git a/src/plugins/acl/acl-api-private.h b/src/plugins/acl/acl-api-private.h index 581a4c1440..e1aeac94f0 100644 --- a/src/plugins/acl/acl-api-private.h +++ b/src/plugins/acl/acl-api-private.h @@ -17,9 +17,9 @@ struct acl_backend_vfuncs { struct acl_mailbox_list_context * (*nonowner_lookups_iter_init)(struct acl_backend *backend); - int (*nonowner_lookups_iter_next)(struct acl_mailbox_list_context *ctx, + bool (*nonowner_lookups_iter_next)(struct acl_mailbox_list_context *ctx, const char **name_r); - void (*nonowner_lookups_iter_deinit) + int (*nonowner_lookups_iter_deinit) (struct acl_mailbox_list_context *ctx); int (*nonowner_lookups_rebuild)(struct acl_backend *backend); @@ -36,9 +36,9 @@ struct acl_backend_vfuncs { struct acl_object_list_iter * (*object_list_init)(struct acl_object *aclobj); - int (*object_list_next)(struct acl_object_list_iter *iter, + bool (*object_list_next)(struct acl_object_list_iter *iter, struct acl_rights *rights_r); - void (*object_list_deinit)(struct acl_object_list_iter *iter); + int (*object_list_deinit)(struct acl_object_list_iter *iter); }; struct acl_backend { @@ -63,6 +63,10 @@ struct acl_backend { struct acl_mailbox_list_context { struct acl_backend *backend; + + bool empty:1; + bool failed:1; + const char *error; }; struct acl_object { @@ -79,16 +83,19 @@ struct acl_object_list_iter { struct acl_rights *rights; unsigned int idx, count; + + bool empty:1; bool failed:1; + const char *error; }; extern const char *const all_mailbox_rights[]; struct acl_object_list_iter * acl_default_object_list_init(struct acl_object *aclobj); -int acl_default_object_list_next(struct acl_object_list_iter *iter, - struct acl_rights *rights_r); -void acl_default_object_list_deinit(struct acl_object_list_iter *iter); +bool acl_default_object_list_next(struct acl_object_list_iter *iter, + struct acl_rights *rights_r); +int acl_default_object_list_deinit(struct acl_object_list_iter *iter); const char *const * acl_backend_mask_get_names(struct acl_backend *backend, diff --git a/src/plugins/acl/acl-api.c b/src/plugins/acl/acl-api.c index 33410a51e7..ff8b10613c 100644 --- a/src/plugins/acl/acl-api.c +++ b/src/plugins/acl/acl-api.c @@ -169,21 +169,21 @@ struct acl_object_list_iter *acl_object_list_init(struct acl_object *aclobj) return aclobj->backend->v.object_list_init(aclobj); } -int acl_object_list_next(struct acl_object_list_iter *iter, +bool acl_object_list_next(struct acl_object_list_iter *iter, struct acl_rights *rights_r) { if (iter->failed) - return -1; + return FALSE; return iter->aclobj->backend->v.object_list_next(iter, rights_r); } -void acl_object_list_deinit(struct acl_object_list_iter **_iter) +int acl_object_list_deinit(struct acl_object_list_iter **_iter) { struct acl_object_list_iter *iter = *_iter; *_iter = NULL; - iter->aclobj->backend->v.object_list_deinit(iter); + return iter->aclobj->backend->v.object_list_deinit(iter); } struct acl_object_list_iter * @@ -213,25 +213,35 @@ acl_default_object_list_init(struct acl_object *aclobj) iter->rights = p_new(pool, struct acl_rights, iter->count); for (i = 0; i < iter->count; i++) acl_rights_dup(&aclobj_rights[i], pool, &iter->rights[i]); - } + } else + iter->empty = TRUE; return iter; } -int acl_default_object_list_next(struct acl_object_list_iter *iter, +bool acl_default_object_list_next(struct acl_object_list_iter *iter, struct acl_rights *rights_r) { if (iter->failed) - return -1; + return FALSE; if (iter->idx == iter->count) - return 0; + return FALSE; *rights_r = iter->rights[iter->idx++]; - return 1; + return TRUE; } -void acl_default_object_list_deinit(struct acl_object_list_iter *iter) +int acl_default_object_list_deinit(struct acl_object_list_iter *iter) { + int ret = 0; + if (iter->failed) + ret = -1; + else if (iter->empty) + ret = 0; + else + ret = 1; + pool_unref(&iter->pool); + return ret; } struct acl_mailbox_list_context * @@ -240,19 +250,18 @@ acl_backend_nonowner_lookups_iter_init(struct acl_backend *backend) return backend->v.nonowner_lookups_iter_init(backend); } -int acl_backend_nonowner_lookups_iter_next(struct acl_mailbox_list_context *ctx, +bool acl_backend_nonowner_lookups_iter_next(struct acl_mailbox_list_context *ctx, const char **name_r) { return ctx->backend->v.nonowner_lookups_iter_next(ctx, name_r); } -void -acl_backend_nonowner_lookups_iter_deinit(struct acl_mailbox_list_context **_ctx) +int acl_backend_nonowner_lookups_iter_deinit(struct acl_mailbox_list_context **_ctx) { struct acl_mailbox_list_context *ctx = *_ctx; *_ctx = NULL; - ctx->backend->v.nonowner_lookups_iter_deinit(ctx); + return ctx->backend->v.nonowner_lookups_iter_deinit(ctx); } int acl_backend_nonowner_lookups_rebuild(struct acl_backend *backend) diff --git a/src/plugins/acl/acl-api.h b/src/plugins/acl/acl-api.h index 91aa82b798..b3a0190cae 100644 --- a/src/plugins/acl/acl-api.h +++ b/src/plugins/acl/acl-api.h @@ -123,10 +123,11 @@ bool acl_backend_rights_match_me(struct acl_backend *backend, /* List mailboxes that have lookup right to some non-owners. */ struct acl_mailbox_list_context * acl_backend_nonowner_lookups_iter_init(struct acl_backend *backend); -int acl_backend_nonowner_lookups_iter_next(struct acl_mailbox_list_context *ctx, +bool acl_backend_nonowner_lookups_iter_next(struct acl_mailbox_list_context *ctx, const char **name_r); -void +int acl_backend_nonowner_lookups_iter_deinit(struct acl_mailbox_list_context **ctx); + /* Force a rebuild for nonowner lookups index */ int acl_backend_nonowner_lookups_rebuild(struct acl_backend *backend); @@ -154,9 +155,9 @@ int acl_object_update(struct acl_object *aclobj, /* List all identifiers. */ struct acl_object_list_iter *acl_object_list_init(struct acl_object *aclobj); -int acl_object_list_next(struct acl_object_list_iter *iter, +bool acl_object_list_next(struct acl_object_list_iter *iter, struct acl_rights *rights_r); -void acl_object_list_deinit(struct acl_object_list_iter **iter); +int acl_object_list_deinit(struct acl_object_list_iter **iter); /* Returns the canonical ID for the right. */ const char *acl_rights_get_id(const struct acl_rights *right); diff --git a/src/plugins/acl/acl-attributes.c b/src/plugins/acl/acl-attributes.c index 63130b26ec..06ed200e8e 100644 --- a/src/plugins/acl/acl-attributes.c +++ b/src/plugins/acl/acl-attributes.c @@ -83,7 +83,7 @@ static int acl_attribute_get_acl(struct mailbox *box, const char *key, } iter = acl_object_list_init(aclobj); - while ((ret = acl_object_list_next(iter, &rights)) > 0) { + while (acl_object_list_next(iter, &rights)) { if (!rights.global && rights.id_type == wanted_rights.id_type && null_strcmp(rights.identifier, wanted_rights.identifier) == 0) { @@ -91,9 +91,8 @@ static int acl_attribute_get_acl(struct mailbox *box, const char *key, break; } } - if (ret < 0) + if ((ret = acl_object_list_deinit(&iter)) < 0) mail_storage_set_internal_error(box->storage); - acl_object_list_deinit(&iter); return ret; } @@ -195,21 +194,19 @@ static const char * acl_attribute_iter_next_acl(struct acl_mailbox_attribute_iter *aiter) { struct acl_rights rights; - int ret; - while ((ret = acl_object_list_next(aiter->acl_iter, &rights)) > 0) { + while (acl_object_list_next(aiter->acl_iter, &rights)) { if (rights.global) continue; str_truncate(aiter->acl_name, strlen(MAILBOX_ATTRIBUTE_PREFIX_ACL)); acl_rights_write_id(aiter->acl_name, &rights); return str_c(aiter->acl_name); } - if (ret < 0) { + if (acl_object_list_deinit(&aiter->acl_iter) < 0) { mail_storage_set_internal_error(aiter->iter.box->storage); aiter->failed = TRUE; return NULL; } - acl_object_list_deinit(&aiter->acl_iter); return NULL; } diff --git a/src/plugins/acl/acl-backend-vfile-acllist.c b/src/plugins/acl/acl-backend-vfile-acllist.c index 7ec62bfc3e..4224d58932 100644 --- a/src/plugins/acl/acl-backend-vfile-acllist.c +++ b/src/plugins/acl/acl-backend-vfile-acllist.c @@ -379,7 +379,7 @@ acl_backend_vfile_nonowner_iter_init(struct acl_backend *_backend) return &ctx->ctx; } -int acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *_ctx, +bool acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *_ctx, const char **name_r) { struct acl_mailbox_list_context_vfile *ctx = @@ -389,22 +389,35 @@ int acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *_ctx, const struct acl_backend_vfile_acllist *acllist; unsigned int count; + if (_ctx->failed) + return FALSE; + acllist = array_get(&backend->acllist, &count); + if (count == 0) + _ctx->empty = TRUE; if (ctx->idx == count) - return 0; + return FALSE; *name_r = acllist[ctx->idx++].name; - return 1; + return TRUE; } -void +int acl_backend_vfile_nonowner_iter_deinit(struct acl_mailbox_list_context *ctx) { struct acl_backend_vfile *backend = (struct acl_backend_vfile *)ctx->backend; + int ret; backend->iterating_acllist = FALSE; + if (ctx->failed) + ret = -1; + else if (ctx->empty) + ret = 0; + else + ret = 1; i_free(ctx); + return ret; } int acl_backend_vfile_nonowner_lookups_rebuild(struct acl_backend *_backend) diff --git a/src/plugins/acl/acl-backend-vfile.h b/src/plugins/acl/acl-backend-vfile.h index b55239ffa9..1fa4d16afc 100644 --- a/src/plugins/acl/acl-backend-vfile.h +++ b/src/plugins/acl/acl-backend-vfile.h @@ -62,9 +62,9 @@ void acl_backend_vfile_acllist_verify(struct acl_backend_vfile *backend, struct acl_mailbox_list_context * acl_backend_vfile_nonowner_iter_init(struct acl_backend *backend); -int acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *ctx, +bool acl_backend_vfile_nonowner_iter_next(struct acl_mailbox_list_context *ctx, const char **name_r); -void +int acl_backend_vfile_nonowner_iter_deinit(struct acl_mailbox_list_context *ctx); int acl_backend_vfile_nonowner_lookups_rebuild(struct acl_backend *backend); diff --git a/src/plugins/acl/doveadm-acl.c b/src/plugins/acl/doveadm-acl.c index 55f2136efc..254292e812 100644 --- a/src/plugins/acl/doveadm-acl.c +++ b/src/plugins/acl/doveadm-acl.c @@ -85,14 +85,13 @@ static int cmd_acl_get_mailbox(struct doveadm_acl_cmd_context *ctx, backend = acl_mailbox_list_get_backend(box->list); iter = acl_object_list_init(aclobj); - while ((ret = acl_object_list_next(iter, &rights)) > 0) T_BEGIN { + while (acl_object_list_next(iter, &rights)) T_BEGIN { if (!ctx->get_match_me || acl_backend_rights_match_me(backend, &rights)) cmd_acl_get_right(&rights); } T_END; - acl_object_list_deinit(&iter); - if (ret < 0) { + if ((ret = acl_object_list_deinit(&iter))<0) { i_error("ACL iteration failed"); doveadm_mail_failed_error(&ctx->ctx, MAIL_ERROR_TEMP); } @@ -445,12 +444,11 @@ static bool cmd_acl_debug_mailbox(struct mailbox *box, bool *retry_r) } iter = acl_backend_nonowner_lookups_iter_init(backend); - while ((ret = acl_backend_nonowner_lookups_iter_next(iter, &name)) > 0) { + while (acl_backend_nonowner_lookups_iter_next(iter, &name)) { if (strcmp(name, box->name) == 0) break; } - acl_backend_nonowner_lookups_iter_deinit(&iter); - if (ret < 0) + if ((ret = acl_backend_nonowner_lookups_iter_deinit(&iter))<0) i_fatal("ACL non-owner iteration failed"); if (ret == 0) { i_error("Mailbox not found from dovecot-acl-list, rebuilding");