view src/plugins/acl/acl-api.c @ 7086:7ed926ed7aa4 HEAD

Updated copyright notices to include year 2008.
author Timo Sirainen <tss@iki.fi>
date Tue, 01 Jan 2008 22:05:21 +0200
parents 414c9d631a81
children e6693a0ec8e1
line wrap: on
line source

/* Copyright (c) 2006-2008 Dovecot authors, see the included COPYING file */

#include "lib.h"
#include "hash.h"
#include "acl-cache.h"
#include "acl-api-private.h"

struct acl_object *acl_object_init_from_name(struct acl_backend *backend,
					     struct mail_storage *storage,
					     const char *name)
{
	return backend->v.object_init(backend, storage, name);
}

void acl_object_deinit(struct acl_object **_aclobj)
{
	struct acl_object *aclobj = *_aclobj;

	*_aclobj = NULL;
	aclobj->backend->v.object_deinit(aclobj);
}

int acl_object_have_right(struct acl_object *aclobj, unsigned int right_idx)
{
	struct acl_backend *backend = aclobj->backend;
	const struct acl_mask *have_mask;

	if (*aclobj->name == '\0') {
		/* we want to look up default rights */
		if (acl_backend_get_default_rights(backend, &have_mask) < 0)
			return -1;
	} else {
		if (backend->v.object_refresh_cache(aclobj) < 0)
			return -1;

		have_mask = acl_cache_get_my_rights(backend->cache,
						    aclobj->name);
		if (have_mask == NULL) {
			if (acl_backend_get_default_rights(backend,
							   &have_mask) < 0)
				return -1;
		}
	}

	return acl_cache_mask_isset(have_mask, right_idx);
}

static int acl_object_get_my_rights_real(struct acl_object *aclobj, pool_t pool,
					 const char *const **rights_r)
{
	struct acl_backend *backend = aclobj->backend;
	const struct acl_mask *mask;
	const char *const *names;
	const char **buf, **rights;
	unsigned int names_count, count, i, j, name_idx;

	if (*aclobj->name == '\0') {
		/* we want to look up default rights */
		if (acl_backend_get_default_rights(backend, &mask) < 0)
			return -1;
	} else {
		if (backend->v.object_refresh_cache(aclobj) < 0)
			return -1;

		mask = acl_cache_get_my_rights(backend->cache,
					       aclobj->name);
		if (mask == NULL) {
			if (acl_backend_get_default_rights(backend, &mask) < 0)
				return -1;
		}
	}

	names = acl_cache_get_names(backend->cache, &names_count);
	buf = t_new(const char *, (mask->size * CHAR_BIT) + 1);
	count = 0;
	for (i = 0, name_idx = 0; i < mask->size; i++) {
		if (mask->mask[i] == 0)
			name_idx += CHAR_BIT;
		else {
			for (j = 1; j < (1 << CHAR_BIT); j <<= 1, name_idx++) {
				if ((mask->mask[j] & j) == 0)
					continue;

				/* @UNSAFE */
				i_assert(name_idx < names_count);
				buf[count++] = p_strdup(pool, names[name_idx]);
			}
		}
	}

	/* @UNSAFE */
	rights = p_new(pool, const char *, count + 1);
	memcpy(rights, buf, count * sizeof(const char *));
	*rights_r = rights;
	return 0;
}

int acl_object_get_my_rights(struct acl_object *aclobj, pool_t pool,
                             const char *const **rights_r)
{
	int ret;

	if (pool->datastack_pool)
		return acl_object_get_my_rights_real(aclobj, pool, rights_r);
	T_FRAME(
		ret = acl_object_get_my_rights_real(aclobj, pool, rights_r);
	);
	return ret;
}

int acl_object_update(struct acl_object *aclobj,
		      const struct acl_rights_update *rights)
{
        return aclobj->backend->v.object_update(aclobj, rights);
}

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,
                         struct acl_rights *rights_r)
{
	if (iter->failed)
		return -1;

	return iter->aclobj->backend->v.object_list_next(iter, rights_r);
}

void 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);
}

struct acl_mailbox_list_context *
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,
					   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)
{
	struct acl_mailbox_list_context *ctx = *_ctx;

	*_ctx = NULL;
	ctx->backend->v.nonowner_lookups_iter_deinit(ctx);
}