void fs_sis_try_unlink_hash_file(struct fs *sis_fs, struct fs_file *super_file) { struct fs_file *hash_file; struct stat st1, st2; const char *dir, *hash, *hash_path; if (fs_sis_path_parse(sis_fs, super_file->path, &dir, &hash) == 0 && fs_stat(super_file, &st1) == 0 && st1.st_nlink == 2) { /* this may be the last link. if hashes/ file is the same, delete it. */ hash_path = t_strdup_printf("%s/"HASH_DIR_NAME"/%s", dir, hash); hash_file = fs_file_init(super_file->fs, hash_path, FS_OPEN_MODE_READONLY); if (fs_stat(hash_file, &st2) == 0 && st1.st_ino == st2.st_ino && CMP_DEV_T(st1.st_dev, st2.st_dev)) { if (fs_delete(hash_file) < 0) i_error("%s", fs_last_error(hash_file->fs)); } fs_file_deinit(&hash_file); } }
int mail_transaction_log_sync_lock(struct mail_transaction_log *log, const char *lock_reason, uint32_t *file_seq_r, uoff_t *file_offset_r) { i_assert(!log->index->log_sync_locked); if (mail_transaction_log_lock_head(log, lock_reason) < 0) return -1; /* update sync_offset */ if (mail_transaction_log_file_map(log->head, log->head->sync_offset, (uoff_t)-1) <= 0) { mail_transaction_log_file_unlock(log->head, t_strdup_printf( "%s - map failed", lock_reason)); return -1; } log->index->log_sync_locked = TRUE; *file_seq_r = log->head->hdr.file_seq; *file_offset_r = log->head->sync_offset; return 0; }
void smtp_server_command_finished(struct smtp_server_command *cmd) { struct smtp_server_connection *conn = cmd->context.conn; struct smtp_server_reply *reply; i_assert(cmd->state < SMTP_SERVER_COMMAND_STATE_FINISHED); cmd->state = SMTP_SERVER_COMMAND_STATE_FINISHED; DLLIST2_REMOVE(&conn->command_queue_head, &conn->command_queue_tail, cmd); conn->command_queue_count--; conn->stats.reply_count++; i_assert(array_is_created(&cmd->replies)); reply = array_idx_modifiable(&cmd->replies, 0); i_assert(reply->content != NULL); if (reply->content->status == 221 || reply->content->status == 421) { i_assert(cmd->replies_expected == 1); if (reply->content->status == 421) { smtp_server_connection_close(&conn, t_strdup_printf( "Server closed the connection: %s", smtp_server_reply_get_one_line(reply))); } else { smtp_server_connection_close(&conn, "Client has quit the connection"); } smtp_server_command_unref(&cmd); return; } else if (cmd->input_locked) { if (cmd->input_captured) smtp_server_connection_input_halt(conn); smtp_server_connection_input_resume(conn); } smtp_server_command_unref(&cmd); smtp_server_connection_trigger_output(conn); }
static bool master_login_auth_input_notfound(struct master_login_auth *auth, const char *args) { struct master_login_auth_request *request; unsigned int id; if (str_to_uint(args, &id) < 0) { i_error("Auth server sent corrupted NOTFOUND line"); return FALSE; } request = master_login_auth_lookup_request(auth, id); if (request != NULL) { const char *reason = t_strdup_printf( "Authenticated user not found from userdb, " "auth lookup id=%u", id); request_internal_failure(request, reason); i_free(request); } return TRUE; }
int client_open_save_dest_box(struct client_command_context *cmd, const char *name, struct mailbox **destbox_r) { struct mail_namespace *ns; struct mailbox *box; const char *error_string; enum mail_error error; ns = client_find_namespace(cmd, &name); if (ns == NULL) return -1; if (cmd->client->mailbox != NULL && mailbox_equals(cmd->client->mailbox, ns, name)) { *destbox_r = cmd->client->mailbox; return 0; } box = mailbox_alloc(ns->list, name, MAILBOX_FLAG_SAVEONLY); if (mailbox_open(box) < 0) { error_string = mailbox_get_last_error(box, &error); if (error == MAIL_ERROR_NOTFOUND) { client_send_tagline(cmd, t_strdup_printf( "NO [TRYCREATE] %s", error_string)); } else { client_send_box_error(cmd, box); } mailbox_free(&box); return -1; } if (cmd->client->enabled_features != 0) { if (mailbox_enable(box, cmd->client->enabled_features) < 0) { client_send_box_error(cmd, box); mailbox_free(&box); return -1; } } *destbox_r = box; return 0; }
static void service_process_log(struct service_process *process, bool default_fatal, const char *str) { const char *data; if (process->service->log_fd[1] == -1) { i_error("%s", str); return; } /* log it via the log process in charge of handling this process's logging */ data = t_strdup_printf("%d %s %s %s\n", process->service->log_process_internal_fd, dec2str(process->pid), default_fatal ? "DEFAULT-FATAL" : "FATAL", str); if (write(process->service->list->master_log_fd[1], data, strlen(data)) < 0) { i_error("write(log process) failed: %m"); i_error("%s", str); } }
static int http_transfer_chunked_parse_size (struct http_transfer_chunked_istream *tcstream) { uoff_t size = 0, prev; /* chunk-size = 1*HEXDIG */ while (tcstream->cur < tcstream->end) { prev = tcstream->chunk_size; if (*tcstream->cur >= '0' && *tcstream->cur <= '9') size = *tcstream->cur-'0'; else if (*tcstream->cur >= 'A' && *tcstream->cur <= 'F') size = *tcstream->cur-'A' + 10; else if (*tcstream->cur >= 'a' && *tcstream->cur <= 'f') size = *tcstream->cur-'a' + 10; else { if (tcstream->parsed_chars == 0) { tcstream->error = t_strdup_printf( "Expected chunk size digit, but found %s", _chr_sanitize(*tcstream->cur)); return -1; } tcstream->parsed_chars = 0; return 1; } tcstream->chunk_size <<= 4; tcstream->chunk_size += size; if (tcstream->chunk_size < prev) { tcstream->error = "Chunk size exceeds integer limit"; return -1; } tcstream->parsed_chars++; tcstream->cur++; } return 0; }
/* <settings checks> */ static bool auth_settings_check(void *_set, pool_t pool, const char **error_r) { struct auth_settings *set = _set; const char *p; if (set->debug_passwords) set->debug = TRUE; if (set->debug) set->verbose = TRUE; if (set->cache_size > 0 && set->cache_size < 1024) { /* probably a configuration error. older versions used megabyte numbers */ *error_r = t_strdup_printf("auth_cache_size value is too small " "(%"PRIuUOFF_T" bytes)", set->cache_size); return FALSE; } if (*set->username_chars == '\0') { /* all chars are allowed */ memset(set->username_chars_map, 1, sizeof(set->username_chars_map)); } else { for (p = set->username_chars; *p != '\0'; p++) set->username_chars_map[(int)(uint8_t)*p] = 1; } if (*set->username_translation != '\0') { p = set->username_translation; for (; *p != '\0' && p[1] != '\0'; p += 2) set->username_translation_map[(int)(uint8_t)*p] = p[1]; } set->realms_arr = (const char *const *)p_strsplit_spaces(pool, set->realms, " "); return TRUE; }
static void test_net_is_in_network(void) { static struct test_net_is_in_network_input input[] = { { "1.2.3.4", "1.2.3.4", 32, TRUE }, { "1.2.3.4", "1.2.3.3", 32, FALSE }, { "1.2.3.4", "1.2.3.5", 32, FALSE }, { "1.2.3.4", "1.2.2.4", 32, FALSE }, { "1.2.3.4", "1.1.3.4", 32, FALSE }, { "1.2.3.4", "0.2.3.4", 32, FALSE }, { "1.2.3.253", "1.2.3.254", 31, FALSE }, { "1.2.3.254", "1.2.3.254", 31, TRUE }, { "1.2.3.255", "1.2.3.254", 31, TRUE }, { "1.2.3.255", "1.2.3.0", 24, TRUE }, { "1.2.255.255", "1.2.254.0", 23, TRUE }, { "255.255.255.255", "128.0.0.0", 1, TRUE }, { "255.255.255.255", "127.0.0.0", 1, FALSE } #ifdef HAVE_IPV6 , { "1234:5678::abcf", "1234:5678::abce", 127, TRUE }, { "1234:5678::abcd", "1234:5678::abce", 127, FALSE }, { "123e::ffff", "123e::0", 15, TRUE }, { "123d::ffff", "123e::0", 15, FALSE } #endif }; struct ip_addr ip, net_ip; unsigned int i; bool success; test_begin("net_is_in_network()"); for (i = 0; i < N_ELEMENTS(input); i++) { test_assert(net_addr2ip(input[i].ip, &ip) == 0); test_assert(net_addr2ip(input[i].net, &net_ip) == 0); success = net_is_in_network(&ip, &net_ip, input[i].bits) == input[i].ret; test_out(t_strdup_printf("net_is_in_network(%u)", i), success); } test_end(); }
static struct dbox_file * mdbox_file_init_full(struct mdbox_storage *storage, uint32_t file_id, bool alt_dir) { struct mdbox_file *file; const char *fname; unsigned int count; file = file_id == 0 ? NULL : mdbox_find_and_move_open_file(storage, file_id); if (file != NULL) { file->file.refcount++; return &file->file; } count = array_count(&storage->open_files); if (count > MDBOX_MAX_OPEN_UNUSED_FILES) { mdbox_close_open_files(storage, count - MDBOX_MAX_OPEN_UNUSED_FILES); } file = i_new(struct mdbox_file, 1); file->storage = storage; file->file.storage = &storage->storage; file->file_id = file_id; fname = file_id == 0 ? dbox_generate_tmp_filename() : t_strdup_printf(MDBOX_MAIL_FILE_FORMAT, file_id); mdbox_file_init_paths(file, fname); dbox_file_init(&file->file); if (alt_dir) file->file.cur_path = file->file.alt_path; if (file_id != 0) array_append(&storage->open_files, &file, 1); else (void)mdbox_file_create(file); return &file->file; }
static int client_input_replicate(struct doveadm_connection *client, const char *const *args) { struct replicator_queue_iter *iter; struct replicator_user *user; const char *usermask; enum replication_priority priority; unsigned int match_count; /* <priority> <username>|<mask> */ if (str_array_length(args) != 2) { i_error("%s: REPLICATE: Invalid parameters", client->conn.name); return -1; } if (replication_priority_parse(args[0], &priority) < 0) { o_stream_send_str(client->conn.output, "-Invalid priority\n"); return 0; } usermask = args[1]; if (strchr(usermask, '*') == NULL && strchr(usermask, '?') == NULL) { replicator_queue_add(client->queue, usermask, priority); o_stream_send_str(client->conn.output, "+1\n"); return 0; } match_count = 0; iter = replicator_queue_iter_init(client->queue); while ((user = replicator_queue_iter_next(iter)) != NULL) { if (!wildcard_match(user->username, usermask)) continue; replicator_queue_add(client->queue, user->username, priority); match_count++; } replicator_queue_iter_deinit(&iter); o_stream_send_str(client->conn.output, t_strdup_printf("+%u\n", match_count)); return 0; }
static int hardlink_replace(const char *src, const char *dest, ino_t src_inode) { const char *p, *destdir, *tmppath; unsigned char randbuf[8]; struct stat st; p = strrchr(dest, '/'); i_assert(p != NULL); destdir = t_strdup_until(dest, p); random_fill_weak(randbuf, sizeof(randbuf)); tmppath = t_strdup_printf("%s/temp.%s.%s.%s", destdir, my_hostname, my_pid, binary_to_hex(randbuf, sizeof(randbuf))); if (link(src, tmppath) < 0) { if (errno == EMLINK) return 0; i_error("link(%s, %s) failed: %m", src, tmppath); return -1; } if (stat(tmppath, &st) < 0) { i_error("stat(%s) failed: %m", tmppath); return -1; } if (st.st_ino != src_inode) { if (unlink(tmppath) < 0) i_error("unlink(%s) failed: %m", tmppath); return 0; } if (rename(tmppath, dest) < 0) { i_error("rename(%s, %s) failed: %m", src, tmppath); if (unlink(tmppath) < 0) i_error("unlink(%s) failed: %m", tmppath); return -1; } return 1; }
static int sieve_attribute_get_default(struct mail_storage *storage, struct sieve_storage *svstorage, struct mail_attribute_value *value_r) { const char *scriptname; int ret; ret = sieve_storage_active_script_get_name(svstorage, &scriptname); if (ret == 0) return sieve_attribute_get_active_script(storage, svstorage, value_r); if (ret > 0) { value_r->value = t_strdup_printf("%c%s", MAILBOX_ATTRIBUTE_SIEVE_DEFAULT_LINK, scriptname); if (sieve_storage_active_script_get_last_change (svstorage, &value_r->last_change) < 0) ret = -1; } if (ret < 0) mail_storage_set_internal_error(storage); return ret; }
const char *message_date_create(time_t timestamp) { struct tm *tm; int offset; bool negative; tm = localtime(×tamp); offset = utc_offset(tm, timestamp); if (offset >= 0) negative = FALSE; else { negative = TRUE; offset = -offset; } return t_strdup_printf("%s, %02d %s %04d %02d:%02d:%02d %c%02d%02d", weekday_names[tm->tm_wday], tm->tm_mday, month_names[tm->tm_mon], tm->tm_year+1900, tm->tm_hour, tm->tm_min, tm->tm_sec, negative ? '-' : '+', offset / 60, offset % 60); }
static const char *test_aqueue2(unsigned int initial_size) { ARRAY(unsigned int) aqueue_array; unsigned int i, j, k; for (i = 0; i < N_ELEMENTS(aqueue_input); i++) { for (k = 0; k < N_ELEMENTS(aqueue_input); k++) { struct aqueue *aqueue; t_array_init(&aqueue_array, initial_size); aqueue = aqueue_init(&aqueue_array.arr); aqueue->head = aqueue->tail = initial_size - 1; for (j = 0; j < k; j++) { aqueue_append(aqueue, &aqueue_input[j]); if (aqueue_count(aqueue) != j + 1) { return t_strdup_printf("Wrong count after append %u vs %u)", aqueue_count(aqueue), j + 1); } if (!aqueue_is_ok(aqueue, UINT_MAX)) return "Invalid data after append"; } if (k != 0 && i < k) { aqueue_delete(aqueue, i); if (aqueue_count(aqueue) != k - 1) return "Wrong count after delete"; if (!aqueue_is_ok(aqueue, i)) return "Invalid data after delete"; } aqueue_clear(aqueue); if (aqueue_count(aqueue) != 0) return "aqueue_clear() broken"; aqueue_deinit(&aqueue); } } return NULL; }
static int acllist_append(struct acl_backend_vfile *backend, struct ostream *output, const char *vname) { struct acl_object *aclobj; struct acl_object_list_iter *iter; struct acl_rights rights; struct acl_backend_vfile_acllist acllist; const char *name; int ret; name = mail_namespace_get_storage_name(backend->backend.list->ns, vname); acl_cache_flush(backend->backend.cache, name); aclobj = acl_object_init_from_name(&backend->backend, name); iter = acl_object_list_init(aclobj); while ((ret = acl_object_list_next(iter, &rights)) > 0) { if (acl_rights_has_nonowner_lookup_changes(&rights)) break; } acl_object_list_deinit(&iter); if (acl_backend_vfile_object_get_mtime(aclobj, &acllist.mtime) < 0) ret = -1; if (ret > 0) { acllist.name = p_strdup(backend->acllist_pool, name); array_append(&backend->acllist, &acllist, 1); T_BEGIN { const char *line; line = t_strdup_printf("%s %s\n", dec2str(acllist.mtime), name); o_stream_send_str(output, line); } T_END; }
void http_server_request_finished(struct http_server_request *req) { struct http_server_connection *conn = req->conn; struct http_server_response *resp = req->response; http_server_tunnel_callback_t tunnel_callback = resp->tunnel_callback; void *tunnel_context = resp->tunnel_context; http_server_request_debug(req, "Finished"); i_assert(req->state < HTTP_SERVER_REQUEST_STATE_FINISHED); req->state = HTTP_SERVER_REQUEST_STATE_FINISHED; http_server_connection_remove_request(conn, req); conn->stats.response_count++; if (tunnel_callback == NULL && (req->req.connection_close || resp->close)) { if (resp->close) { http_server_connection_close(&conn, t_strdup_printf("Server closed connection: %u %s", resp->status, resp->reason)); } else { http_server_connection_close(&conn, "Client requested connection close"); } http_server_request_destroy(&req); return; } http_server_request_destroy(&req); if (tunnel_callback != NULL) { http_server_connection_tunnel(&conn, tunnel_callback, tunnel_context); return; } http_server_connection_trigger_responses(conn); }
static void dsync_replicator_notify(struct dsync_cmd_context *ctx, enum dsync_brain_sync_type sync_type, const char *state_str) { #define REPLICATOR_HANDSHAKE "VERSION\treplicator-doveadm-client\t1\t0\n" const char *path; string_t *str; int fd; path = t_strdup_printf("%s/replicator-doveadm", ctx->ctx.cur_mail_user->set->base_dir); fd = net_connect_unix(path); if (fd == -1) { if (errno == ECONNREFUSED || errno == ENOENT) { /* replicator not running on this server. ignore. */ return; } i_error("net_connect_unix(%s) failed: %m", path); return; } str = t_str_new(128); str_append(str, REPLICATOR_HANDSHAKE"NOTIFY\t"); str_append_tabescaped(str, ctx->ctx.cur_mail_user->username); str_append_c(str, '\t'); if (sync_type == DSYNC_BRAIN_SYNC_TYPE_FULL) str_append_c(str, 'f'); str_append_c(str, '\t'); str_append_tabescaped(str, state_str); str_append_c(str, '\n'); if (write_full(fd, str_data(str), str_len(str)) < 0) i_error("write(%s) failed: %m", path); /* we only wanted to notify replicator. we don't care enough about the answer to wait for it. */ if (close(fd) < 0) i_error("close(%s) failed: %m", path); }
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 openssl_iostream_verify_client_cert(int preverify_ok, X509_STORE_CTX *ctx) { int ssl_extidx = SSL_get_ex_data_X509_STORE_CTX_idx(); SSL *ssl; struct ssl_iostream *ssl_io; char certname[1024]; X509_NAME *subject; ssl = X509_STORE_CTX_get_ex_data(ctx, ssl_extidx); ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index); ssl_io->cert_received = TRUE; subject = X509_get_subject_name(X509_STORE_CTX_get_current_cert(ctx)); if (subject == NULL || X509_NAME_oneline(subject, certname, sizeof(certname)) == NULL) certname[0] = '\0'; else certname[sizeof(certname)-1] = '\0'; /* just in case.. */ if (preverify_ok == 0) { openssl_iostream_set_error(ssl_io, t_strdup_printf( "Received invalid SSL certificate: %s: %s", X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)), certname)); if (ssl_io->verbose_invalid_cert) i_info("%s", ssl_io->last_error); } else if (ssl_io->verbose) { i_info("Received valid SSL certificate: %s", certname); } if (preverify_ok == 0) { ssl_io->cert_broken = TRUE; if (!ssl_io->allow_invalid_cert) { ssl_io->handshake_failed = TRUE; return 0; } } return 1; }
static const char * imapc_list_get_fs_name(struct imapc_mailbox_list *list, const char *name) { struct mailbox_list *fs_list = imapc_list_get_fs(list); struct mail_namespace *ns = list->list.ns; const char *vname; char ns_sep = mail_namespace_get_sep(ns); if (name == NULL) return NULL; vname = mailbox_list_get_vname(&list->list, name); if (list->set->imapc_list_prefix[0] != '\0') { /* put back the prefix, so it gets included in the filesystem. */ unsigned int vname_len = strlen(vname); if (ns->prefix_len > 0) { /* skip over the namespace prefix */ i_assert(strncmp(vname, ns->prefix, ns->prefix_len-1) == 0); if (vname_len == ns->prefix_len-1) vname = ""; else { i_assert(vname[ns->prefix_len-1] == ns_sep); vname += ns->prefix_len; } } if (vname[0] == '\0') { vname = t_strconcat(ns->prefix, list->set->imapc_list_prefix, NULL); } else { vname = t_strdup_printf("%s%s%c%s", ns->prefix, list->set->imapc_list_prefix, ns_sep, vname); } } return mailbox_list_get_storage_name(fs_list, vname); }
static void pop3c_client_authenticate1(struct pop3c_client *client) { const struct pop3c_client_settings *set = &client->set; if (client->set.debug) { if (set->master_user == NULL) { i_debug("pop3c(%s): Authenticating as %s", client->set.host, set->username); } else { i_debug("pop3c(%s): Authenticating as %s for user %s", client->set.host, set->master_user, set->username); } } if (set->master_user == NULL) { o_stream_nsend_str(client->output, t_strdup_printf("USER %s\r\n", set->username)); client->state = POP3C_CLIENT_STATE_USER; } else { client->state = POP3C_CLIENT_STATE_AUTH; o_stream_nsend_str(client->output, "AUTH PLAIN\r\n"); } }
static bool list_parse_directives(struct list_directives_context *ctx, const struct imap_arg *args, const char **error_r) { const char *str; while (imap_arg_get_atom(args, &str) && strncmp(str, "$!", 2) == 0) { str += 2; if (strncmp(str, "unordered", 9) == 0) { if (str[9] == '\0') ; else if (str[9] == '=' && str_to_uint(str + 10, &ctx->chain_count) == 0) ; else { *error_r = "Broken $!unordered directive"; return FALSE; } } else if (strcmp(str, "ordered") == 0 || strcmp(str, "noextra") == 0 || strcmp(str, "extra") == 0 || strncmp(str, "ignore=", 7) == 0 || strncmp(str, "ban=", 4) == 0) { /* ok */ } else { *error_r = t_strdup_printf("Unknown directive: %s", str); return FALSE; } ctx->directives = TRUE; args++; } return TRUE; }
static void login_host_callback(const struct ip_addr *ip, const char *errormsg, void *context) { struct login_host_request *request = context; struct director *dir = request->conn->dir; const char *line, *line_params; unsigned int secs; if (ip == NULL) { if (strncmp(request->line, "OK\t", 3) == 0) line_params = request->line + 3; else if (strncmp(request->line, "PASS\t", 5) == 0) line_params = request->line + 5; else i_panic("BUG: Unexpected line: %s", request->line); i_error("director: User %s host lookup failed: %s", request->username, errormsg); line = t_strconcat("FAIL\t", t_strcut(line_params, '\t'), "\ttemp", NULL); } else if (request->director_proxy_maybe && login_host_request_is_self(request, ip)) { line = request->line; } else { secs = dir->set->director_user_expire / 2; line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u", request->line, net_ip2addr(ip), secs); } login_connection_send_line(request->conn, line); login_connection_unref(&request->conn); i_free(request->username); i_free(request->line); i_free(request); }
int acl_mailbox_update_acl(struct mailbox_transaction_context *t, const struct acl_rights_update *update) { struct acl_object *aclobj; const char *key; time_t ts = update->last_change != 0 ? update->last_change : ioloop_time; key = t_strdup_printf(MAILBOX_ATTRIBUTE_PREFIX_ACL"%s", acl_rights_get_id(&update->rights)); aclobj = acl_mailbox_get_aclobj(t->box); if (acl_object_update(aclobj, update) < 0) { mail_storage_set_critical(t->box->storage, "Failed to set ACL"); return -1; } /* FIXME: figure out some value lengths, so maybe some day quota could apply to ACLs as well. */ if (acl_mailbox_update_removed_id(aclobj, update)) mail_index_attribute_unset(t->itrans, FALSE, key, ts); else mail_index_attribute_set(t->itrans, FALSE, key, ts, 0); return 0; }
static int mbox_write_content_length(struct mbox_save_context *ctx) { uoff_t end_offset; const char *str; size_t len; i_assert(ctx->eoh_offset != (uoff_t)-1); if (ctx->mbox->mbox_writeonly) { /* we can't seek, don't set Content-Length */ return 0; } end_offset = ctx->output->offset; /* write Content-Length headers */ str = t_strdup_printf("\nContent-Length: %s", dec2str(end_offset - ctx->eoh_offset)); len = strlen(str); /* flush manually here so that we don't confuse seek() errors with buffer flushing errors */ if (o_stream_flush(ctx->output) < 0) return write_error(ctx); if (o_stream_seek(ctx->output, ctx->extra_hdr_offset + ctx->space_end_idx - len) < 0) return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()"); if (o_stream_send(ctx->output, str, len) < 0 || o_stream_flush(ctx->output) < 0) return write_error(ctx); if (o_stream_seek(ctx->output, end_offset) < 0) return mbox_set_syscall_error(ctx->mbox, "o_stream_seek()"); return 0; }
int mail_user_init(struct mail_user *user, const char **error_r) { const struct mail_storage_settings *mail_set; const char *home, *key, *value; bool need_home_dir; need_home_dir = user->_home == NULL && settings_vars_have_key(user->set_info, user->set, 'h', "home", &key, &value); /* expand mail_home setting before calling mail_user_get_home() */ settings_var_expand(user->set_info, user->set, user->pool, mail_user_var_expand_table(user)); if (need_home_dir && mail_user_get_home(user, &home) <= 0) { *error_r = t_strdup_printf( "userdb didn't return a home directory, " "but %s used it (%%h): %s", key, value); return -1; } if (mail_user_expand_plugins_envs(user, error_r) < 0) return -1; mail_set = mail_user_set_get_storage_set(user); user->mail_debug = mail_set->mail_debug; user->initialized = TRUE; hook_mail_user_created(user); if (user->error != NULL) { *error_r = t_strdup(user->error); return -1; } return 0; }
/* <settings checks> */ static bool master_service_ssl_settings_check(void *_set, pool_t pool ATTR_UNUSED, const char **error_r) { struct master_service_ssl_settings *set = _set; if (strcmp(set->ssl, "no") == 0) { /* disabled */ return TRUE; } #ifndef HAVE_SSL *error_r = t_strdup_printf("SSL support not compiled in but ssl=%s", set->ssl); return FALSE; #else /* we get called from many different tools, possibly with -O parameter, and few of those tools care about SSL settings. so don't check ssl_cert/ssl_key/etc validity here except in doveconf, because it usually is just an extra annoyance. */ #ifdef CONFIG if (*set->ssl_cert == '\0') { *error_r = "ssl enabled, but ssl_cert not set"; return FALSE; } if (*set->ssl_key == '\0') { *error_r = "ssl enabled, but ssl_key not set"; return FALSE; } #endif if (set->ssl_verify_client_cert && *set->ssl_ca == '\0') { *error_r = "ssl_verify_client_cert set, but ssl_ca not"; return FALSE; } return TRUE; #endif }
static const char * i_stream_mail_get_cached_mail_id(struct mail_istream *mstream) { static const char *headers[] = { "Message-Id", "Date", "Subject" }; struct mail *mail = mstream->mail; enum mail_lookup_abort orig_lookup_abort; const char *value, *ret = ""; unsigned int i; orig_lookup_abort = mail->lookup_abort; mail->lookup_abort = MAIL_LOOKUP_ABORT_NOT_IN_CACHE; for (i = 0; i < N_ELEMENTS(headers); i++) { if (mail_get_first_header(mail, headers[i], &value) > 0) { ret = t_strdup_printf("%s=%s", headers[i], value); break; } } mail->lookup_abort = orig_lookup_abort; return ret; }
static void imapc_sync_add_missing_deleted_flags(struct imapc_sync_context *ctx, uint32_t seq1, uint32_t seq2) { const struct mail_index_record *rec; uint32_t seq, uid1, uid2; const char *cmd; /* if any of them has a missing \Deleted flag, just add it to all of them. */ for (seq = seq1; seq <= seq2; seq++) { rec = mail_index_lookup(ctx->sync_view, seq); if ((rec->flags & MAIL_DELETED) == 0) break; } if (seq <= seq2) { mail_index_lookup_uid(ctx->sync_view, seq1, &uid1); mail_index_lookup_uid(ctx->sync_view, seq2, &uid2); cmd = t_strdup_printf("UID STORE %u:%u +FLAGS \\Deleted", uid1, uid2); imapc_sync_cmd(ctx, cmd); } }