Ejemplo n.º 1
0
int mail_session_connect_parse(const char *const *args, const char **error_r)
{
	struct mail_session *session;
	const char *session_id;
	pid_t pid;
	struct ip_addr ip;
	unsigned int i;

	/* <session id> <username> <service> <pid> [key=value ..] */
	if (str_array_length(args) < 4) {
		*error_r = "CONNECT: Too few parameters";
		return -1;
	}
	session_id = args[0];
	if (str_to_pid(args[3], &pid) < 0) {
		*error_r = t_strdup_printf("CONNECT: Invalid pid %s for session ID %s",
					   args[3], session_id);
		return -1;
	}

	session = hash_table_lookup(mail_sessions_hash, session_id);
	if (session != NULL) {
		*error_r = t_strdup_printf(
			"CONNECT: Duplicate session ID %s for user %s service %s",
			session_id, args[1], args[2]);
		return -1;
	}
	session = i_malloc(sizeof(struct mail_session) + stats_alloc_size());
	session->stats = (void *)(session + 1);
	session->refcount = 1; /* unrefed at disconnect */
	session->id = i_strdup(session_id);
	session->service = str_table_ref(services, args[2]);
	session->pid = pid;
	session->last_update = ioloop_timeval;
	session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS,
				       mail_session_idle_timeout, session);

	session->user = mail_user_login(args[1]);
	for (i = 3; args[i] != NULL; i++) {
		if (strncmp(args[i], "rip=", 4) == 0 &&
		    net_addr2ip(args[i] + 4, &ip) == 0)
			session->ip = mail_ip_login(&ip);
	}

	hash_table_insert(mail_sessions_hash, session->id, session);
	DLLIST_PREPEND_FULL(&stable_mail_sessions, session,
			    stable_prev, stable_next);
	DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session,
			    sorted_prev, sorted_next);
	DLLIST_PREPEND_FULL(&session->user->sessions, session,
			    user_prev, user_next);
	mail_user_ref(session->user);
	if (session->ip != NULL) {
		DLLIST_PREPEND_FULL(&session->ip->sessions, session,
				    ip_prev, ip_next);
		mail_ip_ref(session->ip);
	}
	global_memory_alloc(mail_session_memsize(session));
	return 0;
}
Ejemplo n.º 2
0
static int client_export_iter_user(struct client *client)
{
	struct client_export_cmd *cmd = client->cmd_export;
	struct mail_user *user = client->mail_user_iter;

	i_assert(cmd->level == MAIL_EXPORT_LEVEL_USER);
	mail_user_unref(&client->mail_user_iter);

	if (!cmd->header_sent) {
		o_stream_nsend_str(client->output,
			"user\treset_timestamp\tlast_update"
			"\tnum_logins\tnum_cmds"MAIL_STATS_HEADER);
		cmd->header_sent = TRUE;
	}

	for (; user != NULL; user = user->stable_next) {
		if (client_is_busy(client))
			break;
		if (!mail_export_filter_match_user(&cmd->filter, user))
			continue;

		str_truncate(cmd->str, 0);
		str_append_tabescaped(cmd->str, user->name);
		str_printfa(cmd->str, "\t%ld", (long)user->reset_timestamp);
		client_export_timeval(cmd->str, &user->last_update);
		str_printfa(cmd->str, "\t%u\t%u",
			    user->num_logins, user->num_cmds);
		client_export_mail_stats(cmd->str, &user->stats);
		str_append_c(cmd->str, '\n');
		o_stream_nsend(client->output, str_data(cmd->str),
			       str_len(cmd->str));
	}

	if (user != NULL) {
		client->mail_user_iter = user;
		mail_user_ref(user);
		return 0;
	}
	return 1;
}
Ejemplo n.º 3
0
int mail_session_connect_parse(const char *const *args, const char **error_r)
{
	struct mail_session *session;
	guid_128_t session_guid;
	uint8_t *guid_p;
	pid_t pid;
	struct ip_addr ip;
	unsigned int i;

	/* <session guid> <username> <service> <pid> [key=value ..] */
	if (str_array_length(args) < 4) {
		*error_r = "CONNECT: Too few parameters";
		return -1;
	}
	if (guid_128_from_string(args[0], session_guid) < 0) {
		*error_r = "CONNECT: Invalid GUID";
		return -1;
	}
	if (str_to_pid(args[3], &pid) < 0) {
		*error_r = "CONNECT: Invalid pid";
		return -1;
	}

	guid_p = session_guid;
	session = hash_table_lookup(mail_sessions_hash, guid_p);
	if (session != NULL) {
		*error_r = "CONNECT: Duplicate session GUID";
		return -1;
	}
	session = i_new(struct mail_session, 1);
	session->refcount = 1; /* unrefed at disconnect */
	session->service = i_strdup(args[2]);
	memcpy(session->guid, session_guid, sizeof(session->guid));
	session->pid = pid;
	session->last_update = ioloop_timeval;
	session->to_idle = timeout_add(MAIL_SESSION_IDLE_TIMEOUT_MSECS,
				       mail_session_idle_timeout, session);

	session->user = mail_user_login(args[1]);
	for (i = 3; args[i] != NULL; i++) {
		if (strncmp(args[i], "rip=", 4) == 0 &&
		    net_addr2ip(args[i] + 4, &ip) == 0)
			session->ip = mail_ip_login(&ip);
	}

	guid_p = session->guid;
	hash_table_insert(mail_sessions_hash, guid_p, session);
	DLLIST_PREPEND_FULL(&stable_mail_sessions, session,
			    stable_prev, stable_next);
	DLLIST2_APPEND_FULL(&mail_sessions_head, &mail_sessions_tail, session,
			    sorted_prev, sorted_next);
	DLLIST_PREPEND_FULL(&session->user->sessions, session,
			    user_prev, user_next);
	mail_user_ref(session->user);
	if (session->ip != NULL) {
		DLLIST_PREPEND_FULL(&session->ip->sessions, session,
				    ip_prev, ip_next);
		mail_ip_ref(session->ip);
	}
	global_memory_alloc(mail_session_memsize(session));
	return 0;
}
Ejemplo n.º 4
0
static bool client_export_iter_init(struct client *client)
{
	struct client_export_cmd *cmd = client->cmd_export;

	if (cmd->filter.user != NULL && strchr(cmd->filter.user, '*') == NULL &&
	    (cmd->level == MAIL_EXPORT_LEVEL_USER ||
	     cmd->level == MAIL_EXPORT_LEVEL_SESSION)) {
		/* exact user */
		struct mail_user *user = mail_user_lookup(cmd->filter.user);
		if (user == NULL)
			return FALSE;
		if (cmd->level == MAIL_EXPORT_LEVEL_SESSION) {
			client->mail_session_iter = user->sessions;
			if (client->mail_session_iter == NULL)
				return FALSE;
			mail_session_ref(client->mail_session_iter);
			cmd->export_iter = client_export_iter_session;
		} else {
			client->mail_user_iter = user;
			mail_user_ref(user);
			cmd->export_iter = client_export_iter_user;
		}
		return TRUE;
	}
	if (cmd->filter.ip_bits == IPADDR_BITS(&cmd->filter.ip) &&
	    (cmd->level == MAIL_EXPORT_LEVEL_IP ||
	     cmd->level == MAIL_EXPORT_LEVEL_SESSION)) {
		/* exact IP address */
		struct mail_ip *ip = mail_ip_lookup(&cmd->filter.ip);
		if (ip == NULL)
			return FALSE;
		if (cmd->level == MAIL_EXPORT_LEVEL_SESSION) {
			client->mail_session_iter = ip->sessions;
			if (client->mail_session_iter == NULL)
				return FALSE;
			mail_session_ref(client->mail_session_iter);
			cmd->export_iter = client_export_iter_session;
		} else {
			client->mail_ip_iter = ip;
			mail_ip_ref(ip);
			cmd->export_iter = client_export_iter_ip;
		}
		return TRUE;
	}
	if (cmd->filter.domain != NULL &&
	    strchr(cmd->filter.domain, '*') == NULL &&
	    (cmd->level == MAIL_EXPORT_LEVEL_DOMAIN ||
	     cmd->level == MAIL_EXPORT_LEVEL_USER)) {
		/* exact domain */
		struct mail_domain *domain =
			mail_domain_lookup(cmd->filter.domain);
		if (domain == NULL)
			return FALSE;
		if (cmd->level == MAIL_EXPORT_LEVEL_USER) {
			client->mail_user_iter = domain->users;
			mail_user_ref(client->mail_user_iter);
			cmd->export_iter = client_export_iter_user;
		} else {
			client->mail_domain_iter = domain;
			mail_domain_ref(domain);
			cmd->export_iter = client_export_iter_domain;
		}
		return TRUE;
	}

	switch (cmd->level) {
	case MAIL_EXPORT_LEVEL_COMMAND:
		client->mail_cmd_iter = stable_mail_commands_head;
		if (client->mail_cmd_iter == NULL)
			return FALSE;
		mail_command_ref(client->mail_cmd_iter);
		cmd->export_iter = client_export_iter_command;
		break;
	case MAIL_EXPORT_LEVEL_SESSION:
		client->mail_session_iter = stable_mail_sessions;
		if (client->mail_session_iter == NULL)
			return FALSE;
		mail_session_ref(client->mail_session_iter);
		cmd->export_iter = client_export_iter_session;
		break;
	case MAIL_EXPORT_LEVEL_USER:
		client->mail_user_iter = stable_mail_users;
		if (client->mail_user_iter == NULL)
			return FALSE;
		mail_user_ref(client->mail_user_iter);
		cmd->export_iter = client_export_iter_user;
		break;
	case MAIL_EXPORT_LEVEL_DOMAIN:
		client->mail_domain_iter = stable_mail_domains;
		if (client->mail_domain_iter == NULL)
			return FALSE;
		mail_domain_ref(client->mail_domain_iter);
		cmd->export_iter = client_export_iter_domain;
		break;
	case MAIL_EXPORT_LEVEL_IP:
		client->mail_ip_iter = stable_mail_ips;
		if (client->mail_ip_iter == NULL)
			return FALSE;
		mail_ip_ref(client->mail_ip_iter);
		cmd->export_iter = client_export_iter_ip;
		break;
	}
	i_assert(cmd->export_iter != NULL);
	return TRUE;
}