Exemplo n.º 1
0
void acl_mailbox_allocated(struct mailbox *box)
{
	struct acl_mailbox_list *alist = ACL_LIST_CONTEXT(box->list);
	struct mailbox_vfuncs *v = box->vlast;
	struct acl_mailbox *abox;
	bool ignore_acls = (box->flags & MAILBOX_FLAG_IGNORE_ACLS) != 0;

	if (alist == NULL) {
		/* ACLs disabled */
		return;
	}

	if (mail_namespace_is_shared_user_root(box->list->ns)) {
		/* this is the root shared namespace, which itself doesn't
		   have any existing mailboxes. */
		ignore_acls = TRUE;
	}

	abox = p_new(box->pool, struct acl_mailbox, 1);
	abox->module_ctx.super = *v;
	box->vlast = &abox->module_ctx.super;
	/* aclobj can be used for setting ACLs, even when mailbox is opened
	   with IGNORE_ACLS flag */
	abox->aclobj = acl_object_init_from_name(alist->rights.backend,
						 mailbox_get_name(box));

	v->free = acl_mailbox_free;
	if (!ignore_acls) {
		abox->acl_enabled = TRUE;
		v->is_readonly = acl_is_readonly;
		v->exists = acl_mailbox_exists;
		v->open = acl_mailbox_open;
		v->get_status = acl_mailbox_get_status;
		v->create_box = acl_mailbox_create;
		v->update_box = acl_mailbox_update;
		v->delete_box = acl_mailbox_delete;
		v->rename_box = acl_mailbox_rename;
		v->save_begin = acl_save_begin;
		v->copy = acl_copy;
		v->transaction_commit = acl_transaction_commit;
		v->attribute_set = acl_attribute_set;
		v->attribute_get = acl_attribute_get;
		v->attribute_iter_init = acl_attribute_iter_init;
		v->attribute_iter_next = acl_attribute_iter_next;
		v->attribute_iter_deinit = acl_attribute_iter_deinit;
	}
	MODULE_CONTEXT_SET(box, acl_storage_module, abox);
}
static int
mailbox_list_subscription_fill_one(struct mailbox_list *list,
				   struct mailbox_list *src_list,
				   const char *name)
{
	struct mail_namespace *ns, *default_ns = list->ns;
	struct mail_namespace *namespaces = default_ns->user->namespaces;
	struct mailbox_node *node;
	const char *vname, *ns_name, *error;
	unsigned int len;
	bool created;

	/* default_ns is whatever namespace we're currently listing.
	   if we have e.g. prefix="" and prefix=pub/ namespaces with
	   pub/ namespace having subscriptions=no, we want to:

	   1) when listing "" namespace we want to skip over any names
	   that begin with pub/. */
	if (src_list->ns->prefix_len == 0)
		ns_name = name;
	else {
		/* we could have two-level namespace: ns/ns2/ */
		ns_name = t_strconcat(src_list->ns->prefix, name, NULL);
	}
	ns = mail_namespace_find_unsubscribable(namespaces, ns_name);
	if (ns != NULL && ns != default_ns) {
		if (ns->prefix_len > 0)
			return 0;
		/* prefix="" namespace=no : catching this is basically the
		   same as not finding any namespace. */
		ns = NULL;
	}

	/* 2) when listing pub/ namespace, skip over entries that don't
	   begin with pub/. */
	if (ns == NULL &&
	    (default_ns->flags & NAMESPACE_FLAG_SUBSCRIPTIONS) == 0)
		return 0;

	/* When listing shared namespace's subscriptions, we need to
	   autocreate all the visible child namespaces. their subscriptions
	   are listed later. */
	if (ns != NULL && mail_namespace_is_shared_user_root(ns)) {
		/* we'll need to get the namespace autocreated.
		   one easy way is to just ask to join a reference and
		   pattern */
		(void)mailbox_list_join_refpattern(ns->list, ns_name, "");
	}

	/* When listing pub/ namespace, skip over the namespace
	   prefix in the name. the rest of the name is storage_name. */
	if (ns == NULL)
		ns = default_ns;
	else if (strncmp(ns_name, ns->prefix, ns->prefix_len) == 0) {
		ns_name += ns->prefix_len;
		name = ns_name;
	} else {
		/* "pub" entry - this shouldn't be possible normally, because
		   it should be saved as "pub/", but handle it anyway */
		i_assert(strncmp(ns_name, ns->prefix, ns->prefix_len-1) == 0 &&
			 ns_name[ns->prefix_len-1] == '\0');
		name = ns_name = "";
	}

	len = strlen(name);
	if (len > 0 && name[len-1] == mail_namespace_get_sep(ns)) {
		/* entry ends with hierarchy separator, remove it.
		   this exists mainly for backwards compatibility with old
		   Dovecot versions and non-Dovecot software that added them */
		name = t_strndup(name, len-1);
	}

	if (!mailbox_list_is_valid_name(list, name, &error)) {
		/* we'll only get into trouble if we show this */
		return -1;
	} else {
		vname = mailbox_list_get_vname(list, name);
		if (!uni_utf8_str_is_valid(vname))
			return -1;
		node = mailbox_tree_get(list->subscriptions, vname, &created);
		node->flags = MAILBOX_SUBSCRIBED;
	}
	return 0;
}