コード例 #1
0
ファイル: acl-mailbox.c プロジェクト: jwm/dovecot-notmuch
static int acl_mailbox_get_status(struct mailbox *box,
                                  enum mailbox_status_items items,
                                  struct mailbox_status *status_r)
{
    struct acl_mailbox *abox = ACL_CONTEXT(box);

    if (abox->module_ctx.super.get_status(box, items, status_r) < 0)
        return -1;

    if ((items & STATUS_PERMANENT_FLAGS) != 0) {
        if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) <= 0) {
            status_r->permanent_flags &= MAIL_DELETED|MAIL_SEEN;
            status_r->permanent_keywords = FALSE;
            status_r->allow_new_keywords = FALSE;
        }
        if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) <= 0)
            status_r->permanent_flags &= ~MAIL_DELETED;
        if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) <= 0)
            status_r->permanent_flags &= ~MAIL_SEEN;
    }
    return 0;
}
コード例 #2
0
ファイル: acl-mailbox.c プロジェクト: jwm/dovecot-notmuch
static int acl_mailbox_open_check_acl(struct mailbox *box)
{
    struct acl_mailbox *abox = ACL_CONTEXT(box);
    struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
    const unsigned int *idx_arr = alist->rights.acl_storage_right_idx;
    enum acl_storage_rights open_right;
    int ret;

    /* mailbox can be opened either for reading or appending new messages */
    if ((box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0 ||
            (box->list->ns->flags & NAMESPACE_FLAG_NOACL) != 0 ||
            abox->skip_acl_checks)
        return 0;

    if ((box->flags & MAILBOX_FLAG_SAVEONLY) != 0) {
        open_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
                     ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
    } else {
        open_right = ACL_STORAGE_RIGHT_READ;
    }

    ret = acl_object_have_right(abox->aclobj, idx_arr[open_right]);
    if (ret <= 0) {
        if (ret == 0) {
            /* no access. */
            acl_mailbox_fail_not_found(box);
        }
        return -1;
    }
    if (open_right != ACL_STORAGE_RIGHT_READ) {
        ret = acl_object_have_right(abox->aclobj,
                                    idx_arr[ACL_STORAGE_RIGHT_READ]);
        if (ret < 0)
            return -1;
        if (ret == 0)
            abox->no_read_right = TRUE;
    }
    return 0;
}
コード例 #3
0
ファイル: acl-mailbox.c プロジェクト: jwm/dovecot-notmuch
int acl_mailbox_right_lookup(struct mailbox *box, unsigned int right_idx)
{
    struct acl_mailbox *abox = ACL_CONTEXT(box);
    struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
    int ret;

    if (abox->skip_acl_checks)
        return 1;

    ret = acl_object_have_right(abox->aclobj,
                                alist->rights.acl_storage_right_idx[right_idx]);
    if (ret > 0)
        return 1;
    if (ret < 0) {
        mail_storage_set_internal_error(box->storage);
        return -1;
    }

    mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
                           MAIL_ERRSTR_NO_PERMISSION);
    return 0;
}
コード例 #4
0
ファイル: acl-mailbox.c プロジェクト: bsmr-dovecot/core
static int
acl_mailbox_create(struct mailbox *box, const struct mailbox_update *update,
		   bool directory)
{
	struct acl_mailbox *abox = ACL_CONTEXT(box);
	int ret;

	if (!mailbox_is_autocreated(box)) {
		/* we're looking up CREATE permission from our parent's rights */
		ret = acl_mailbox_list_have_right(box->list, box->name, TRUE,
						  ACL_STORAGE_RIGHT_CREATE, NULL);
	} else {
		/* mailbox is autocreated, so we need to treat it as if it
		   already exists. ignore the "create" ACL here. */
		ret = 1;
	}
	if (ret <= 0) {
		if (ret < 0) {
			mail_storage_set_internal_error(box->storage);
			return -1;
		}
		/* Note that if user didn't have LOOKUP permission to parent
		   mailbox, this may reveal the mailbox's existence to user.
		   Can't help it. */
		mail_storage_set_error(box->storage, MAIL_ERROR_PERM,
				       MAIL_ERRSTR_NO_PERMISSION);
		return -1;
	}

	/* ignore ACLs in this mailbox until creation is complete, because
	   super.create() may call e.g. mailbox_open() which will fail since
	   we haven't yet copied ACLs to this mailbox. */
	abox->skip_acl_checks = TRUE;
	ret = abox->module_ctx.super.create_box(box, update, directory);
	abox->skip_acl_checks = FALSE;
	if (ret == 0)
		acl_mailbox_copy_acls_from_parent(box);
	return ret;
}
コード例 #5
0
static void acl_mailbox_copy_acls_from_parent(struct mailbox *box)
{
	struct acl_mailbox *abox = ACL_CONTEXT(box);
	struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
	struct acl_object *parent_aclobj;
	struct acl_object_list_iter *iter;
	struct acl_rights_update update;

	memset(&update, 0, sizeof(update));
	update.modify_mode = ACL_MODIFY_MODE_REPLACE;
	update.neg_modify_mode = ACL_MODIFY_MODE_REPLACE;

	parent_aclobj = acl_object_init_from_parent(alist->rights.backend,
						    box->name);
	iter = acl_object_list_init(parent_aclobj);
	while (acl_object_list_next(iter, &update.rights) > 0) {
		/* don't copy global ACL rights. */
		if (!update.rights.global)
			(void)acl_object_update(abox->aclobj, &update);
	}
	acl_object_list_deinit(&iter);
	acl_object_deinit(&parent_aclobj);
}
コード例 #6
0
static bool acl_is_readonly(struct mailbox *box)
{
	struct acl_mailbox *abox = ACL_CONTEXT(box);
	enum acl_storage_rights save_right;

	if (abox->module_ctx.super.is_readonly(box))
		return TRUE;

	save_right = (box->flags & MAILBOX_FLAG_POST_SESSION) != 0 ?
		ACL_STORAGE_RIGHT_POST : ACL_STORAGE_RIGHT_INSERT;
	if (acl_mailbox_right_lookup(box, save_right) > 0)
		return FALSE;
	if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_EXPUNGE) > 0)
		return FALSE;

	if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE) > 0)
		return FALSE;
	if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_DELETED) > 0)
		return FALSE;
	if (acl_mailbox_right_lookup(box, ACL_STORAGE_RIGHT_WRITE_SEEN) > 0)
		return FALSE;

	return TRUE;
}
コード例 #7
0
struct acl_object *acl_mailbox_get_aclobj(struct mailbox *box)
{
	struct acl_mailbox *abox = ACL_CONTEXT(box);

	return abox->aclobj;
}