Skip to content

Commit

Permalink
acl-plugin: Make iterators more conforming
Browse files Browse the repository at this point in the history
The *_next functions return true/false, deinit will
report errors and end result.
  • Loading branch information
cmouse authored and GitLab committed Sep 7, 2016
1 parent ae53308 commit 37c72fa
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 44 deletions.
21 changes: 14 additions & 7 deletions src/plugins/acl/acl-api-private.h
Expand Up @@ -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);

Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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,
Expand Down
37 changes: 23 additions & 14 deletions src/plugins/acl/acl-api.c
Expand Up @@ -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 *
Expand Down Expand Up @@ -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 *
Expand All @@ -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)
Expand Down
9 changes: 5 additions & 4 deletions src/plugins/acl/acl-api.h
Expand Up @@ -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);

Expand Down Expand Up @@ -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);
Expand Down
11 changes: 4 additions & 7 deletions src/plugins/acl/acl-attributes.c
Expand Up @@ -83,17 +83,16 @@ 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) {
value_r->value = acl_rights_export(&rights);
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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
21 changes: 17 additions & 4 deletions src/plugins/acl/acl-backend-vfile-acllist.c
Expand Up @@ -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 =
Expand All @@ -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)
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/acl/acl-backend-vfile.h
Expand Up @@ -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);

Expand Down
10 changes: 4 additions & 6 deletions src/plugins/acl/doveadm-acl.c
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 37c72fa

Please sign in to comment.