Exemple #1
0
static int handle_ssl_error(struct ssl_proxy *proxy, int error)
{
	if (!gnutls_error_is_fatal(error)) {
		if (!verbose_ssl)
			return 0;

		if (error == GNUTLS_E_WARNING_ALERT_RECEIVED) {
			i_warning("Received SSL warning alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Non-fatal SSL error: %s: %s",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		}
		return 0;
	}

	if (verbose_ssl) {
		/* fatal error occurred */
		if (error == GNUTLS_E_FATAL_ALERT_RECEIVED) {
			i_warning("Received SSL fatal alert: %s [%s]",
				  get_alert_text(proxy),
				  net_ip2addr(&proxy->ip));
		} else {
			i_warning("Error reading from SSL client: %s [%s]",
				  gnutls_strerror(error),
				  net_ip2addr(&proxy->ip));
		}
	}

        gnutls_alert_send_appropriate(proxy->session, error);
	ssl_proxy_destroy(proxy);
	return -1;
}
static void send_msg_data(msg_data_t *msg_data)
{
	const char *push_notify_path = PUSH_NOTIFY_PATH;

	int soc = socket( AF_UNIX, SOCK_STREAM, 0 );
	if ( soc < 0 ) {
		i_warning( "open notify socket failed(%d): %m", soc );
		return;
	}

	struct sockaddr_un sock_addr;
	memset( &sock_addr, 0, sizeof(struct sockaddr_un));
	sock_addr.sun_family = AF_UNIX;
	i_strocpy( sock_addr.sun_path, push_notify_path, sizeof(sock_addr.sun_path) );
	socklen_t sock_len = sizeof(sock_addr.sun_family) + strlen(sock_addr.sun_path) + 1;
	int rc = connect(soc, (struct sockaddr *) &sock_addr, sock_len);
	if ( rc < 0 ) {
		i_warning("connect to notify socket %s failed: %m",
			  push_notify_path);
		close(soc);
		return;
	}

	rc = send(soc, msg_data, sizeof(*msg_data), 0);
	if ( rc < 0 )
		i_warning("send to notify socket %s failed: %m",
			  push_notify_path);

	close(soc);
}
Exemple #3
0
static void openssl_info_callback(const SSL *ssl, int where, int ret)
{
	struct ssl_iostream *ssl_io;

	ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
	if ((where & SSL_CB_ALERT) != 0) {
		switch (ret & 0xff) {
		case SSL_AD_CLOSE_NOTIFY:
			i_debug("%sSSL alert: %s",
				ssl_io->log_prefix,
				SSL_alert_desc_string_long(ret));
			break;
		default:
			i_warning("%sSSL alert: where=0x%x, ret=%d: %s %s",
				  ssl_io->log_prefix, where, ret,
				  SSL_alert_type_string_long(ret),
				  SSL_alert_desc_string_long(ret));
			break;
		}
	} else if (ret == 0) {
		i_warning("%sSSL failed: where=0x%x: %s",
			  ssl_io->log_prefix, where, SSL_state_string_long(ssl));
	} else {
		i_debug("%sSSL: where=0x%x, ret=%d: %s",
			ssl_io->log_prefix, where, ret,
			SSL_state_string_long(ssl));
	}
}
Exemple #4
0
static int maildir_fix_duplicate(struct maildir_sync_context *ctx,
				 const char *dir, const char *fname2)
{
	const char *fname1, *path1, *path2;
	const char *new_fname, *new_path;
	struct stat st1, st2;

	fname1 = maildir_uidlist_sync_get_full_filename(ctx->uidlist_sync_ctx,
							fname2);
	i_assert(fname1 != NULL);

	path1 = t_strconcat(dir, "/", fname1, NULL);
	path2 = t_strconcat(dir, "/", fname2, NULL);

	if (stat(path1, &st1) < 0 || stat(path2, &st2) < 0) {
		/* most likely the files just don't exist anymore.
		   don't really care about other errors much. */
		return 0;
	}
	if (st1.st_ino == st2.st_ino &&
	    CMP_DEV_T(st1.st_dev, st2.st_dev)) {
		/* Files are the same. this means either a race condition
		   between stat() calls, or that the files were link()ed. */
		if (st1.st_nlink > 1 && st2.st_nlink == st1.st_nlink &&
		    st1.st_ctime == st2.st_ctime &&
		    st1.st_ctime < ioloop_time - DUPE_LINKS_DELETE_SECS) {
			/* The file has hard links and it hasn't had any
			   changes (such as renames) for a while, so this
			   isn't a race condition.

			   rename()ing one file on top of the other would fix
			   this safely, except POSIX decided that rename()
			   doesn't work that way. So we'll have unlink() one
			   and hope that another process didn't just decide to
			   unlink() the other (uidlist lock prevents this from
			   happening) */
			if (unlink(path2) == 0)
				i_warning("Unlinked a duplicate: %s", path2);
			else {
				mail_storage_set_critical(
					&ctx->mbox->storage->storage,
					"unlink(%s) failed: %m", path2);
			}
		}
		return 0;
	}

	new_fname = maildir_filename_generate();
	new_path = t_strconcat(ctx->mbox->box.path, "/new/", new_fname, NULL);

	if (rename(path2, new_path) == 0)
		i_warning("Fixed a duplicate: %s -> %s", path2, new_fname);
	else if (errno != ENOENT) {
		mail_storage_set_critical(&ctx->mbox->storage->storage,
			"Couldn't fix a duplicate: rename(%s, %s) failed: %m",
			path2, new_path);
		return -1;
	}
	return 0;
}
static int replication_notify_sync(struct mail_user *user)
{
	struct replication_user *ruser = REPLICATION_USER_CONTEXT(user);
	string_t *str;
	char buf[1024];
	int fd;
	ssize_t ret;

	fd = net_connect_unix(ruser->socket_path);
	if (fd == -1) {
		i_error("net_connect_unix(%s) failed: %m", ruser->socket_path);
		return -1;
	}
	net_set_nonblock(fd, FALSE);

	/* <username> \t "sync" */
	str = t_str_new(256);
	str_append_tabescaped(str, user->username);
	str_append(str, "\tsync\n");
	alarm(ruser->sync_secs);
	if (write_full(fd, str_data(str), str_len(str)) < 0) {
		i_error("write(%s) failed: %m", ruser->socket_path);
		ret = -1;
	} else {
		/* + | - */
		ret = read(fd, buf, sizeof(buf));
		if (ret < 0) {
			if (errno != EINTR) {
				i_error("read(%s) failed: %m",
					ruser->socket_path);
			} else {
				i_warning("replication(%s): Sync failure: "
					  "Timeout in %u secs",
					  user->username, ruser->sync_secs);
			}
		} else if (ret == 0) {
			i_error("read(%s) failed: EOF", ruser->socket_path);
			ret = -1;
		} else if (buf[0] == '+') {
			/* success */
			ret = 0;
		} else if (buf[0] == '-') {
			/* failure */
			if (buf[ret-1] == '\n') ret--;
			i_warning("replication(%s): Sync failure: %s",
				  user->username, t_strndup(buf+1, ret-1));
			ret = -1;
		} else {
			i_warning("replication(%s): "
				  "Remote sent invalid input: %s",
				  user->username, t_strndup(buf, ret));
		}
	}
	alarm(0);
	if (close(fd) < 0)
		i_error("close(%s) failed: %m", ruser->socket_path);
	return ret;
}
static void ring_noconn_warning(struct director *dir)
{
	if (!dir->ring_handshaked) {
		i_warning("Delaying all requests "
			  "until all directors have connected");
	} else {
		i_warning("Delaying new user requests until ring is synced");
	}
	dir->ring_handshake_warning_sent = TRUE;
	timeout_remove(&dir->to_handshake_warning);
}
struct pop3c_client *
pop3c_client_init(const struct pop3c_client_settings *set)
{
	struct pop3c_client *client;
	struct ssl_iostream_settings ssl_set;
	const char *error;
	pool_t pool;

	// CLEANUP: Remove Warning
	i_warning("pop3c_client_init called");

	pool = pool_alloconly_create("pop3c client", 1024);
	client = p_new(pool, struct pop3c_client, 1);
	client->pool = pool;
	client->fd = -1;

	client->set.debug = set->debug;
	client->set.host = p_strdup(pool, set->host);
	client->set.port = set->port;
	client->set.master_user = p_strdup_empty(pool, set->master_user);
	client->set.username = p_strdup(pool, set->username);

	// CLEANUP: remove warning
	i_warning("pop3c_client_init: username %s", client->set.username);
	env_put(t_strconcat("POP3C_USERNAME="******"pop3c(%s:%u): Couldn't initialize SSL context: %s",
				set->host, set->port, error);
		}
	}
	return client;
}
Exemple #8
0
static void
packet_received(u_char *args, const struct pcap_pkthdr *h, const u_char *sp)
{
    FW_handle_T handle = (FW_handle_T) args;
    struct fw_handle *fwh = handle->fwh;
    sa_family_t af;
    u_int8_t hdrlen;
    u_int32_t caplen = h->caplen;
    const struct ip *ip = NULL;
    const struct pfloghdr *hdr;
    char addr[INET6_ADDRSTRLEN] = { '\0' };
    int track_outbound;

    track_outbound = Config_get_int(handle->config, "track_outbound",
                                    "firewall", TRACK_OUTBOUND);

    hdr = (const struct pfloghdr *)sp;
    if(hdr->length < MIN_PFLOG_HDRLEN) {
        i_warning("invalid pflog header length (%u/%u). "
            "packet dropped.", hdr->length, MIN_PFLOG_HDRLEN);
        return;
    }
    hdrlen = BPF_WORDALIGN(hdr->length);

    if(caplen < hdrlen) {
        i_warning("pflog header larger than caplen (%u/%u). "
            "packet dropped.", hdrlen, caplen);
        return;
    }

    /* We're interested in passed packets */
    if(hdr->action != PF_PASS)
        return;

    af = hdr->af;
    if(af == AF_INET) {
        ip = (const struct ip *) (sp + hdrlen);
        if(hdr->dir == PF_IN) {
            inet_ntop(af, &ip->ip_src, addr,
                      sizeof(addr));
        }
        else if(hdr->dir == PF_OUT && track_outbound) {
            inet_ntop(af, &ip->ip_dst, addr,
                      sizeof(addr));
        }
    }

    if(addr[0] != '\0') {
        i_debug("packet received: direction = %s, addr = %s",
                (hdr->dir == PF_IN ? "in" : "out"), addr);
        List_insert_after(fwh->entries, strdup(addr));
    }
}
Exemple #9
0
static void mail_session_id_lost(const char *session_id)
{
	if (ioloop_time < session_id_warn_hide_until) {
		if (session_id_hide_warned)
			return;
		session_id_hide_warned = TRUE;
		i_warning("stats process appears to have crashed/restarted, "
			  "hiding missing session ID warnings for %d seconds",
			  (int)(session_id_warn_hide_until - ioloop_time));
		return;
	}
	i_warning("Couldn't find session ID: %s", session_id);
}
Exemple #10
0
static void sig_die(const siginfo_t *si, void *context)
{
	struct master_service *service = context;

	/* SIGINT comes either from master process or from keyboard. we don't
	   want to log it in either case.*/
	if (si->si_signo != SIGINT) {
		i_warning("Killed with signal %d (by pid=%s uid=%s code=%s)",
			  si->si_signo, dec2str(si->si_pid),
			  dec2str(si->si_uid),
			  lib_signal_code_to_str(si->si_signo, si->si_code));
	} else if ((service->flags & MASTER_SERVICE_FLAG_NO_IDLE_DIE) != 0) {
		/* never die when idling */
		return;
	} else if ((service->flags & MASTER_SERVICE_FLAG_STANDALONE) == 0) {
		/* SIGINT came from master. die only if we're not handling
		   any clients currently. */
		if (service->master_status.available_count !=
		    service->total_available_count)
			return;

		if (service->idle_die_callback != NULL &&
		    !service->idle_die_callback()) {
			/* we don't want to die - send a notification to master
			   so it doesn't think we're ignoring it completely. */
			master_status_send(service, FALSE);
			return;
		}
	}

	service->killed = TRUE;
	io_loop_stop(service->ioloop);
}
Exemple #11
0
static bool
ssl_params_verify(struct ssl_params *param,
		  const unsigned char *data, size_t size)
{
	unsigned int bitsize, len;
	bool found = FALSE;

	/* <bitsize><length><data>... */
	while (size >= sizeof(bitsize)) {
		memcpy(&bitsize, data, sizeof(bitsize));
		if (bitsize == 0) {
			if (found)
				return TRUE;
			i_warning("Regenerating %s for ssl_dh_parameters_length=%u",
				  param->path, param->set.ssl_dh_parameters_length);
			return FALSE;
		}
		data += sizeof(bitsize);
		size -= sizeof(bitsize);
		if (bitsize == param->set.ssl_dh_parameters_length)
			found = TRUE;

		if (size < sizeof(len))
			break;
		memcpy(&len, data, sizeof(len));
		if (len > size - sizeof(len))
			break;
		data += sizeof(bitsize) + len;
		size -= sizeof(bitsize) + len;
	}
	i_error("Corrupted %s", param->path);
	return FALSE;
}
static void mail_storage_service_time_moved(time_t old_time, time_t new_time)
{
	long diff = new_time - old_time;

	if (diff > 0) {
		if (diff > MAX_NOWARN_FORWARD_SECS)
			i_warning("Time jumped forwards %ld seconds", diff);
		return;
	}
	diff = -diff;

	if (diff > MAX_TIME_BACKWARDS_SLEEP) {
		i_fatal("Time just moved backwards by %ld seconds. "
			"This might cause a lot of problems, "
			"so I'll just kill myself now. "
			"http://wiki2.dovecot.org/TimeMovedBackwards", diff);
	} else {
		i_error("Time just moved backwards by %ld seconds. "
			"I'll sleep now until we're back in present. "
			"http://wiki2.dovecot.org/TimeMovedBackwards", diff);
		/* Sleep extra second to make sure usecs also grows. */
		diff++;

		while (diff > 0 && sleep(diff) != 0) {
			/* don't use sleep()'s return value, because
			   it could get us to a long loop in case
			   interrupts just keep coming */
			diff = old_time - time(NULL) + 1;
		}
	}
}
Exemple #13
0
int
Mod_fw_open(FW_handle_T handle)
{
    struct fw_handle *fwh = NULL;
    char *pfdev_path;
    int pfdev;

    pfdev_path = Config_get_str(handle->config, "pfdev_path",
                                "firewall", PFDEV_PATH);

    if((fwh = malloc(sizeof(*fwh))) == NULL)
        return -1;

    pfdev = open(pfdev_path, O_RDWR);
    if(pfdev < 1 || pfdev > MAX_PFDEV) {
        i_warning("could not open %s: %s", pfdev_path,
                  strerror(errno));
        return -1;
    }

    fwh->pfdev = pfdev;
    fwh->pcap_handle = NULL;
    handle->fwh = fwh;

    return 0;
}
Exemple #14
0
int
Mod_fw_open(FW_handle_T handle)
{
    struct fw_handle *fwh = NULL;
    char *npfdev_path;
    int npfdev;

    npfdev_path = Config_get_str(handle->config, "npfdev_path",
                                "firewall", NPFDEV_PATH);

    if((fwh = malloc(sizeof(*fwh))) == NULL)
        return -1;

    npfdev = open(npfdev_path, O_RDONLY);
    if(npfdev < 1) {
        i_warning("could not open %s: %s", npfdev_path,
                  strerror(errno));
        return -1;
    }

    fwh->npfdev = npfdev;
    fwh->pcap_handle = NULL;
    handle->fwh = fwh;

    return 0;
}
Exemple #15
0
static void io_loop_default_time_moved(time_t old_time, time_t new_time)
{
	if (old_time > new_time) {
		i_warning("Time moved backwards by %ld seconds.",
			  (long)(old_time - new_time));
	}
}
void mail_transaction_log_file_unlock(struct mail_transaction_log_file *file,
				      const char *lock_reason)
{
	unsigned int lock_time;

	if (!file->locked)
		return;

	file->locked = FALSE;
	file->locked_sync_offset_updated = FALSE;

	if (MAIL_TRANSACTION_LOG_FILE_IN_MEMORY(file))
		return;

	lock_time = time(NULL) - file->lock_created;
	if (lock_time >= MAIL_TRANSACTION_LOG_LOCK_WARN_SECS && lock_reason != NULL) {
		i_warning("Transaction log file %s was locked for %u seconds (%s)",
			  file->filepath, lock_time, lock_reason);
	}

	if (file->log->index->lock_method == FILE_LOCK_METHOD_DOTLOCK) {
		(void)mail_transaction_log_file_undotlock(file);
		return;
	}

	file_unlock(&file->file_lock);
}
Exemple #17
0
void testsuite_smtp_deinit(void)
{
	if ( unlink_directory(testsuite_smtp_tmp, TRUE) < 0 )
		i_warning("failed to remove temporary directory '%s': %m.",
			testsuite_smtp_tmp);
	
	pool_unref(&testsuite_smtp_pool);		
}
Exemple #18
0
static void testsuite_tmp_dir_deinit(void)
{
	if ( unlink_directory(testsuite_tmp_dir, TRUE) < 0 )
		i_warning("failed to remove temporary directory '%s': %m.",
			testsuite_tmp_dir);

	i_free(testsuite_tmp_dir);
}
void testsuite_binary_deinit(void)
{
	if ( unlink_directory(testsuite_binary_tmp, TRUE) < 0 ) {
		i_warning("failed to remove temporary directory '%s': %m.",
			testsuite_binary_tmp);
	}

	i_free(testsuite_binary_tmp);
}
Exemple #20
0
static void openssl_info_callback(const SSL *ssl, int where, int ret)
{
    struct ssl_iostream *ssl_io;

    ssl_io = SSL_get_ex_data(ssl, dovecot_ssl_extdata_index);
    if ((where & SSL_CB_ALERT) != 0) {
        i_warning("%s: SSL alert: where=0x%x, ret=%d: %s %s",
                  ssl_io->source, where, ret,
                  SSL_alert_type_string_long(ret),
                  SSL_alert_desc_string_long(ret));
    } else if (ret == 0) {
        i_warning("%s: SSL failed: where=0x%x: %s",
                  ssl_io->source, where, SSL_state_string_long(ssl));
    } else {
        i_debug("%s: SSL: where=0x%x, ret=%d: %s",
                ssl_io->source, where, ret,
                SSL_state_string_long(ssl));
    }
}
Exemple #21
0
static void
passwd_check_warnings(struct auth_request *auth_request,
		      struct passwd_userdb_module *module,
		      const struct timeval *start_tv)
{
	struct timeval end_tv;
	unsigned int msecs, percentage;

	if (gettimeofday(&end_tv, NULL) < 0)
		return;

	msecs = timeval_diff_msecs(&end_tv, start_tv);
	if (msecs >= PASSWD_SLOW_WARN_MSECS) {
		i_warning("passwd: Lookup for %s took %u secs",
			  auth_request->user, msecs/1000);
		return;
	}
	if (worker || module->slow_warned)
		return;

	if (msecs < PASSWD_SLOW_MASTER_WARN_MSECS) {
		module->fast_count++;
		return;
	}
	module->slow_count++;
	if (module->fast_count + module->slow_count <
	    PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL)
		return;

	percentage = module->slow_count * 100 /
		(module->slow_count + module->fast_count);
	if (percentage < PASSDB_SLOW_MASTER_WARN_MIN_PERCENTAGE) {
		/* start from beginning */
		module->slow_count = module->fast_count = 0;
	} else {
		i_warning("passwd: %u%% of last %u lookups took over "
			  "%u milliseconds, "
			  "you may want to set blocking=yes for userdb",
			  percentage, PASSDB_SLOW_MASTER_WARN_COUNT_INTERVAL,
			  PASSWD_SLOW_MASTER_WARN_MSECS);
		module->slow_warned = TRUE;
	}
}
Exemple #22
0
void mailbox_guid_cache_refresh(struct mailbox_list *list)
{
	struct mailbox_list_iterate_context *ctx;
	const struct mailbox_info *info;
	struct mailbox *box;
	struct mailbox_metadata metadata;
	struct mailbox_guid_cache_rec *rec;
	uint8_t *guid_p;

	if (!hash_table_is_created(list->guid_cache)) {
		list->guid_cache_pool =
			pool_alloconly_create("guid cache", 1024*16);
		hash_table_create(&list->guid_cache, list->guid_cache_pool, 0,
				  guid_128_hash, guid_128_cmp);
	} else {
		hash_table_clear(list->guid_cache, TRUE);
		p_clear(list->guid_cache_pool);
	}
	list->guid_cache_invalidated = FALSE;
	list->guid_cache_updated = FALSE;
	list->guid_cache_errors = FALSE;

	ctx = mailbox_list_iter_init(list, "*",
				     MAILBOX_LIST_ITER_SKIP_ALIASES |
				     MAILBOX_LIST_ITER_NO_AUTO_BOXES);
	while ((info = mailbox_list_iter_next(ctx)) != NULL) {
		if ((info->flags &
		     (MAILBOX_NOSELECT | MAILBOX_NONEXISTENT)) != 0)
			continue;

		box = mailbox_alloc(list, info->vname, 0);
		if (mailbox_get_metadata(box, MAILBOX_METADATA_GUID,
					 &metadata) < 0) {
			i_error("Couldn't get mailbox %s GUID: %s",
				info->vname, mailbox_get_last_internal_error(box, NULL));
			list->guid_cache_errors = TRUE;
		} else if ((rec = hash_table_lookup(list->guid_cache,
				(const uint8_t *)metadata.guid)) != NULL) {
			i_warning("Mailbox %s has duplicate GUID with %s: %s",
				  info->vname, rec->vname,
				  guid_128_to_string(metadata.guid));
		} else {
			rec = p_new(list->guid_cache_pool,
				    struct mailbox_guid_cache_rec, 1);
			memcpy(rec->guid, metadata.guid, sizeof(rec->guid));
			rec->vname = p_strdup(list->guid_cache_pool, info->vname);
			guid_p = rec->guid;
			hash_table_insert(list->guid_cache, guid_p, rec);
		}
		mailbox_free(&box);
	}
	if (mailbox_list_iter_deinit(&ctx) < 0)
		list->guid_cache_errors = TRUE;
}
static bool
auth_request_check_spid(struct master_login_auth *auth,
			struct master_login_auth_request *req)
{
	if (auth->auth_server_pid != req->auth_pid && auth->spid_received) {
		/* auth server was restarted. don't even attempt a login. */
		i_warning("Auth server restarted (pid %u -> %u), aborting auth",
			  (unsigned int)req->auth_pid,
			  (unsigned int)auth->auth_server_pid);
		return FALSE;
	}
	return TRUE;
}
Exemple #24
0
static void mail_session_idle_timeout(struct mail_session *session)
{
	/* user="" service="" pid=0 is used for incoming sessions that were
	   received after we detected a stats process crash/restart. there's
	   no point in logging anything about them, since they contain no
	   useful information. */
	if (session->user->name[0] == '\0' && session->service[0] != '\0' &&
	    session->pid == 0) {
		i_warning("Session %s (user %s, service %s) "
			  "appears to have crashed, disconnecting it",
			  session->id, session->user->name, session->service);
	}
	mail_session_disconnect(session);
}
static int maildir_handle_uid_insertion(struct maildir_index_sync_context *ctx,
					enum maildir_uidlist_rec_flag uflags,
					const char *filename, uint32_t uid)
{
	int ret;

	if ((uflags & MAILDIR_UIDLIST_REC_FLAG_NONSYNCED) != 0) {
		/* partial syncing */
		return 0;
	}

	/* most likely a race condition: we read the maildir, then someone else
	   expunged messages and committed changes to index. so, this message
	   shouldn't actually exist. */
	if ((uflags & MAILDIR_UIDLIST_REC_FLAG_RACING) == 0) {
		/* mark it racy and check in next sync */
		ctx->mbox->maildir_hdr.cur_check_time = 0;
		maildir_sync_set_racing(ctx->maildir_sync_ctx);
		maildir_uidlist_add_flags(ctx->mbox->uidlist, filename,
					  MAILDIR_UIDLIST_REC_FLAG_RACING);
		return 0;
	}

	if (ctx->uidlist_sync_ctx == NULL) {
		ret = maildir_uidlist_sync_init(ctx->mbox->uidlist,
						MAILDIR_UIDLIST_SYNC_PARTIAL |
						MAILDIR_UIDLIST_SYNC_KEEP_STATE,
						&ctx->uidlist_sync_ctx);
		if (ret <= 0)
			return -1;
	}

	uflags &= MAILDIR_UIDLIST_REC_FLAG_NEW_DIR;
	maildir_uidlist_sync_remove(ctx->uidlist_sync_ctx, filename);
	ret = maildir_uidlist_sync_next(ctx->uidlist_sync_ctx,
					filename, uflags);
	i_assert(ret > 0);

	/* give the new UID to it immediately */
	maildir_uidlist_sync_finish(ctx->uidlist_sync_ctx);

	i_warning("Maildir %s: Expunged message reappeared, giving a new UID "
		  "(old uid=%u, file=%s)%s", mailbox_get_path(&ctx->mbox->box),
		  uid, filename, strncmp(filename, "msg.", 4) != 0 ? "" :
		  " (Your MDA is saving MH files into Maildir?)");
	return 0;
}
int auth_server_connection_connect(struct auth_server_connection *conn)
{
	const char *handshake;
	int fd;

	i_assert(!conn->connected);
	i_assert(conn->fd == -1);

	conn->last_connect = ioloop_time;
	timeout_remove(&conn->to);

	/* max. 1 second wait here. */
	fd = net_connect_unix_with_retries(conn->client->auth_socket_path,
					   1000);
	if (fd == -1) {
		if (errno == EACCES) {
			i_error("auth: %s",
				eacces_error_get("connect",
					conn->client->auth_socket_path));
		} else {
			i_error("auth: connect(%s) failed: %m",
				conn->client->auth_socket_path);
		}
		return -1;
	}
	conn->fd = fd;
	conn->io = io_add(fd, IO_READ, auth_server_connection_input, conn);
	conn->input = i_stream_create_fd(fd, AUTH_SERVER_CONN_MAX_LINE_LENGTH);
	conn->output = o_stream_create_fd(fd, (size_t)-1);
	conn->connected = TRUE;

	handshake = t_strdup_printf("VERSION\t%u\t%u\nCPID\t%u\n",
				    AUTH_CLIENT_PROTOCOL_MAJOR_VERSION,
                                    AUTH_CLIENT_PROTOCOL_MINOR_VERSION,
				    conn->client->client_pid);
	if (o_stream_send_str(conn->output, handshake) < 0) {
		i_warning("Error sending handshake to auth server: %s",
			  o_stream_get_error(conn->output));
		auth_server_connection_disconnect(conn,
			o_stream_get_error(conn->output));
		return -1;
	}

	conn->to = timeout_add(AUTH_HANDSHAKE_TIMEOUT,
			       auth_client_handshake_timeout, conn);
	return 0;
}
Exemple #27
0
void passdb_cache_init(const struct auth_settings *set)
{
	rlim_t limit;

	if (set->cache_size == 0 || set->cache_ttl == 0)
		return;

	if (restrict_get_process_size(&limit) == 0 &&
	    set->cache_size > limit) {
		i_warning("auth_cache_size (%luM) is higher than "
			  "process VSZ limit (%luM)",
			  (unsigned long)(set->cache_size/1024/1024),
			  (unsigned long)(limit/1024/1024));
	}
	passdb_cache = auth_cache_new(set->cache_size, set->cache_ttl,
				      set->cache_negative_ttl);
}
Exemple #28
0
static int
maildir_rename_empty_basename(struct maildir_sync_context *ctx,
			      const char *dir, const char *fname)
{
	const char *old_path, *new_fname, *new_path;

	old_path = t_strconcat(dir, "/", fname, NULL);
	new_fname = maildir_filename_generate();
	new_path = t_strconcat(mailbox_get_path(&ctx->mbox->box),
			       "/new/", new_fname, NULL);
	if (rename(old_path, new_path) == 0)
		i_warning("Fixed broken filename: %s -> %s", old_path, new_fname);
	else if (errno != ENOENT) {
		mail_storage_set_critical(&ctx->mbox->storage->storage,
			"Couldn't fix a broken filename: rename(%s, %s) failed: %m",
			old_path, new_path);
		return -1;
	}
	return 0;
}
static void auth_worker_send_reply(struct auth_worker_client *client,
				   struct auth_request *request,
				   string_t *str)
{
	time_t cmd_duration = time(NULL) - client->cmd_start;
	const char *p;

	if (worker_restart_request)
		o_stream_nsend_str(client->output, "RESTART\n");
	o_stream_nsend(client->output, str_data(str), str_len(str));
	if (o_stream_nfinish(client->output) < 0 && request != NULL &&
	    cmd_duration > AUTH_WORKER_WARN_DISCONNECTED_LONG_CMD_SECS) {
		p = strchr(str_c(str), '\t');
		p = p == NULL ? "BUG" : t_strcut(p+1, '\t');

		i_warning("Auth master disconnected us while handling "
			  "request for %s for %ld secs (result=%s)",
			  request->user, (long)cmd_duration, p);
	}
}
static int maildir_sync_index_finish(struct maildir_index_sync_context *ctx,
				     bool success)
{
	struct maildir_mailbox *mbox = ctx->mbox;
	unsigned int time_diff;
	int ret = success ? 0 : -1;

	time_diff = time(NULL) - ctx->start_time;
	if (time_diff >= MAILDIR_SYNC_TIME_WARN_SECS) {
		i_warning("Maildir %s: Synchronization took %u seconds "
			  "(%u new msgs, %u flag change attempts, "
			  "%u expunge attempts)",
			  mailbox_get_path(&ctx->mbox->box), time_diff,
			  ctx->new_msgs_count, ctx->flag_change_count,
			  ctx->expunge_count);
		mail_index_sync_no_warning(ctx->sync_ctx);
	}

	if (ret < 0)
		mail_index_sync_rollback(&ctx->sync_ctx);
	else {
		maildir_sync_index_update_ext_header(ctx);

		/* Set syncing_commit=TRUE so that if any sync callbacks try
		   to access mails which got lost (eg. expunge callback trying
		   to open the file which was just unlinked) we don't try to
		   start a second index sync and crash. */
		mbox->syncing_commit = TRUE;
		if (mail_index_sync_commit(&ctx->sync_ctx) < 0) {
			mailbox_set_index_error(&mbox->box);
			ret = -1;
		}
		mbox->syncing_commit = FALSE;
	}

	index_storage_expunging_deinit(&mbox->box);
	maildir_keywords_sync_deinit(&ctx->keywords_sync_ctx);
	index_sync_changes_deinit(&ctx->sync_changes);
	i_free(ctx);
	return ret;
}