static void fts_solr_set_default_ns(struct solr_fts_backend *backend) { struct mail_namespace *ns = backend->backend.ns; struct fts_solr_user *fuser = FTS_SOLR_USER_CONTEXT(ns->user); const struct fts_solr_settings *set = &fuser->set; const char *str; if (backend->default_ns != NULL) return; if (set->default_ns_prefix != NULL) { backend->default_ns = mail_namespace_find_prefix(ns->user->namespaces, set->default_ns_prefix); if (backend->default_ns == NULL) { i_error("fts_solr: default_ns setting points to " "nonexistent namespace"); } } if (backend->default_ns == NULL) { backend->default_ns = mail_namespace_find_inbox(ns->user->namespaces); } while (backend->default_ns->alias_for != NULL) backend->default_ns = backend->default_ns->alias_for; if (ns != backend->default_ns) { str = solr_escape_id_str(ns->prefix); backend->id_namespace = i_strdup(str); } }
static int lmtp_rcpt_to_is_over_quota(struct client *client, const struct mail_recipient *rcpt) { struct mail_user *user; struct mail_namespace *ns; struct mailbox *box; struct mailbox_status status; const char *errstr; enum mail_error error; int ret; if (!client->lmtp_set->lmtp_rcpt_check_quota) return 0; ret = mail_storage_service_next(storage_service, rcpt->service_user, &user); if (ret < 0) return -1; ns = mail_namespace_find_inbox(user->namespaces); box = mailbox_alloc(ns->list, "INBOX", 0); ret = mailbox_get_status(box, STATUS_CHECK_OVER_QUOTA, &status); if (ret < 0) { errstr = mailbox_get_last_error(box, &error); if (error == MAIL_ERROR_NOSPACE) { client_send_line(client, "552 5.2.2 <%s> %s", rcpt->address, errstr); ret = 1; } } mailbox_free(&box); mail_user_unref(&user); return ret; }
static struct mail_namespace * mail_user_find_attribute_namespace(struct mail_user *user) { struct mail_namespace *ns; ns = mail_namespace_find_inbox(user->namespaces); if (ns != NULL) return ns; for (ns = user->namespaces; ns != NULL; ns = ns->next) { if (ns->type == MAIL_NAMESPACE_TYPE_PRIVATE) return ns; } return NULL; }
static int cmd_mailbox_metadata_open_mailbox(struct metadata_cmd_context *mctx, struct mail_user *user, const char *op, struct mail_namespace **ns_r, struct mailbox **box_r) { mctx->empty_mailbox_name = mctx->mailbox[0] == '\0'; if (mctx->empty_mailbox_name) { if (!mctx->ctx.allow_empty_mailbox_name) { i_error("Failed to %s: %s", op, "mailbox name cannot be empty"); mctx->ctx.exit_code = EX_USAGE; return -1; } /* server attribute */ *ns_r = mail_namespace_find_inbox(user->namespaces); *box_r = mailbox_alloc((*ns_r)->list, "INBOX", 0); mctx->key = t_strconcat(MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER, mctx->key, NULL); } else { /* mailbox attributes */ *ns_r = mail_namespace_find(user->namespaces, mctx->mailbox); *box_r = mailbox_alloc((*ns_r)->list, mctx->mailbox, 0); } if (mailbox_open(*box_r) < 0) { i_error("Failed to open mailbox: %s", mailbox_get_last_error(*box_r, NULL)); doveadm_mail_failed_mailbox(&mctx->ctx, *box_r); mailbox_free(box_r); return -1; } return 0; }
static int fts_namespace_find(struct mail_user *user, const char *ns_prefix, struct mail_namespace **ns_r) { struct mail_namespace *ns; if (ns_prefix == NULL) ns = mail_namespace_find_inbox(user->namespaces); else { ns = mail_namespace_find_prefix(user->namespaces, ns_prefix); if (ns == NULL) { i_error("Namespace prefix not found: %s", ns_prefix); return -1; } } if (fts_list_backend(ns->list) == NULL) { i_error("fts not enabled for user's namespace %s", ns_prefix); return -1; } *ns_r = ns; return 0; }
struct mail_namespace * client_find_namespace_full(struct client *client, const char **mailbox, const char **error_r) { struct mail_namespace *namespaces = client->user->namespaces; struct mail_namespace *ns; string_t *utf8_name; utf8_name = t_str_new(64); if (imap_utf7_to_utf8(*mailbox, utf8_name) < 0) { *error_r = "NO Mailbox name is not valid mUTF-7"; return NULL; } ns = mail_namespace_find(namespaces, str_c(utf8_name)); if ((ns->flags & NAMESPACE_FLAG_AUTOCREATED) != 0 && ns->prefix_len == 0) { /* this matched only the autocreated prefix="" namespace. give a nice human-readable error message */ *error_r = t_strdup_printf( "NO Client tried to access nonexistent namespace. " "(Mailbox name should probably be prefixed with: %s)", mail_namespace_find_inbox(namespaces)->prefix); return NULL; } if ((client->set->parsed_workarounds & WORKAROUND_TB_EXTRA_MAILBOX_SEP) != 0 && str_len(utf8_name) > 0 && str_c(utf8_name)[str_len(utf8_name)-1] == mail_namespace_get_sep(ns)) { /* drop the extra trailing hierarchy separator */ str_truncate(utf8_name, str_len(utf8_name)-1); } *mailbox = str_c(utf8_name); return ns; }
static int virtual_config_parse_line(struct virtual_parse_context *ctx, const char *line, const char **error_r) { struct mail_user *user = ctx->mbox->storage->storage.user; struct virtual_backend_box *bbox; const char *p; bool no_wildcards = FALSE; if (*line == ' ' || *line == '\t') { /* continues the previous search rule */ if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) { *error_r = "Search rule without a mailbox"; return -1; } while (*line == ' ' || *line == '\t') line++; str_append_c(ctx->rule, ' '); str_append(ctx->rule, line); return 0; } /* if there is no rule yet, it means we want the previous mailboxes to use the rule that comes later */ if (str_len(ctx->rule) > 0) { if (virtual_config_add_rule(ctx, error_r) < 0) return -1; } if (!uni_utf8_str_is_valid(line)) { *error_r = t_strdup_printf("Mailbox name not UTF-8: %s", line); return -1; } /* new mailbox. the search args are added to it later. */ bbox = p_new(ctx->pool, struct virtual_backend_box, 1); bbox->virtual_mbox = ctx->mbox; if (strcasecmp(line, "INBOX") == 0) line = "INBOX"; bbox->name = p_strdup(ctx->pool, line); switch (bbox->name[0]) { case '+': bbox->name++; bbox->clear_recent = TRUE; break; case '-': bbox->name++; bbox->negative_match = TRUE; break; case '!': /* save messages here */ if (ctx->mbox->save_bbox != NULL) { *error_r = "Multiple save mailboxes defined"; return -1; } bbox->name++; ctx->mbox->save_bbox = bbox; no_wildcards = TRUE; break; } if (bbox->name[0] == '/') { /* [+-!]/metadata entry:value */ if ((p = strchr(bbox->name, ':')) == NULL) { *error_r = "':' separator missing between metadata entry name and value"; return -1; } bbox->metadata_entry = p_strdup_until(ctx->pool, bbox->name, p++); bbox->metadata_value = p; if (!imap_metadata_verify_entry_name(bbox->metadata_entry, error_r)) return -1; no_wildcards = TRUE; } if (!no_wildcards && (strchr(bbox->name, '*') != NULL || strchr(bbox->name, '%') != NULL)) { bbox->glob = imap_match_init(ctx->pool, bbox->name, TRUE, ctx->sep); ctx->have_wildcards = TRUE; } if (bbox->metadata_entry == NULL) { /* now that the prefix characters have been processed, find the namespace */ bbox->ns = strcasecmp(bbox->name, "INBOX") == 0 ? mail_namespace_find_inbox(user->namespaces) : mail_namespace_find(user->namespaces, bbox->name); if (bbox->ns == NULL) { *error_r = t_strdup_printf("Namespace not found for %s", bbox->name); return -1; } if (strcmp(bbox->name, ctx->mbox->box.vname) == 0) { *error_r = "Virtual mailbox can't point to itself"; return -1; } ctx->have_mailbox_defines = TRUE; } array_append(&ctx->mbox->backend_boxes, &bbox, 1); return 0; }
static int virtual_config_parse_line(struct virtual_parse_context *ctx, const char *line, const char **error_r) { struct mail_user *user = ctx->mbox->storage->storage.user; struct virtual_backend_box *bbox; const char *name; if (*line == ' ' || *line == '\t') { /* continues the previous search rule */ if (ctx->rule_idx == array_count(&ctx->mbox->backend_boxes)) { *error_r = "Search rule without a mailbox"; return -1; } while (*line == ' ' || *line == '\t') line++; str_append_c(ctx->rule, ' '); str_append(ctx->rule, line); return 0; } /* if there is no rule yet, it means we want the previous mailboxes to use the rule that comes later */ if (str_len(ctx->rule) > 0) { if (virtual_config_add_rule(ctx, error_r) < 0) return -1; } /* new mailbox. the search args are added to it later. */ bbox = p_new(ctx->pool, struct virtual_backend_box, 1); if (strcasecmp(line, "INBOX") == 0) line = "INBOX"; bbox->name = p_strdup(ctx->pool, line); if (*line == '-' || *line == '+' || *line == '!') line++; bbox->ns = strcasecmp(line, "INBOX") == 0 ? mail_namespace_find_inbox(user->namespaces) : mail_namespace_find(user->namespaces, line); if (!uni_utf8_str_is_valid(bbox->name)) { *error_r = t_strdup_printf("Mailbox name not UTF-8: %s", bbox->name); return -1; } if (bbox->ns == NULL) { *error_r = t_strdup_printf("Namespace not found for %s", bbox->name); return -1; } if (bbox->name[0] == '+') { bbox->name++; bbox->clear_recent = TRUE; } if (strchr(bbox->name, '*') != NULL || strchr(bbox->name, '%') != NULL) { name = bbox->name[0] == '-' ? bbox->name + 1 : bbox->name; bbox->glob = imap_match_init(ctx->pool, name, TRUE, ctx->sep); ctx->have_wildcards = TRUE; } else if (bbox->name[0] == '!') { /* save messages here */ if (ctx->mbox->save_bbox != NULL) { *error_r = "Multiple save mailboxes defined"; return -1; } bbox->name++; ctx->mbox->save_bbox = bbox; } ctx->have_mailbox_defines = TRUE; array_append(&ctx->mbox->backend_boxes, &bbox, 1); return 0; }
bool cmd_setmetadata(struct client_command_context *cmd) { struct imap_setmetadata_context *ctx; const struct imap_arg *args; const char *mailbox; struct mail_namespace *ns; int ret; ret = imap_parser_read_args(cmd->parser, 2, IMAP_PARSE_FLAG_STOP_AT_LIST, &args); if (ret == -1) { client_send_command_error(cmd, NULL); return TRUE; } if (ret == -2) return FALSE; if (!imap_arg_get_astring(&args[0], &mailbox) || args[1].type != IMAP_ARG_LIST) { client_send_command_error(cmd, "Invalid arguments."); return TRUE; } if (!cmd->client->imap_metadata_enabled) { client_send_command_error(cmd, "METADATA disabled."); return TRUE; } ctx = p_new(cmd->pool, struct imap_setmetadata_context, 1); ctx->cmd = cmd; ctx->cmd->context = ctx; if (mailbox[0] == '\0') { /* server attribute */ ctx->key_prefix = MAILBOX_ATTRIBUTE_PREFIX_DOVECOT_PVT_SERVER; ns = mail_namespace_find_inbox(cmd->client->user->namespaces); mailbox = "INBOX"; } else { ns = client_find_namespace(cmd, &mailbox); if (ns == NULL) return TRUE; } if (cmd->client->mailbox != NULL && !cmd->client->mailbox_examined && mailbox_equals(cmd->client->mailbox, ns, mailbox)) ctx->box = cmd->client->mailbox; else { ctx->box = mailbox_alloc(ns->list, mailbox, 0); if (mailbox_open(ctx->box) < 0) { client_send_box_error(cmd, ctx->box); mailbox_free(&ctx->box); return TRUE; } } ctx->trans = mailbox_transaction_begin(ctx->box, 0); /* we support large literals, so read the values from client asynchronously the same way as APPEND does. */ cmd->client->input_lock = cmd; ctx->parser = imap_parser_create(cmd->client->input, cmd->client->output, cmd->client->set->imap_max_line_length); o_stream_unset_flush_callback(cmd->client->output); cmd->func = cmd_setmetadata_continue; cmd->context = ctx; return cmd_setmetadata_continue(cmd); }